gastables/AUTHORS0000644000175000017500000000017110765136255013154 0ustar varunvarunVarun Hiremath Venkattraman A C Shyam Sundar gastables/COPYING0000644000175000017500000004311010765136255013137 0ustar varunvarun GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gastables/gui/0000755000175000017500000000000011303442601012651 5ustar varunvarungastables/gui/PKG-INFO0000644000175000017500000000101411303442576013755 0ustar varunvarunName: gastables Version: 0.3 Summary: GUI for compressible flow gastable modules Home-page: http://code.google.com/p/python-gastables/ Author: Varun Hiremath, Venkattraman A License: GPL Description: Gas Tables include modules for compressible gas flow calculations. The main modules currently included are: - Isentropic Relations - Normal Shock Relations - Oblique Shock Relations - Fanno Flow - Isothermal Flow - Rayleigh Flow - Prandtl Meyer Function . Homepage: http://code.google.com/p/python-gastables/ gastables/gui/gastables0000755000175000017500000005140011303442576014557 0ustar varunvarun#!/usr/bin/python """ GUI for Gas Tables """ """ * Copyright (C) 2008 Varun Hiremath * Copyright (C) 2008 A Venkattraman * Copyright (C) 2008 C Shyam Sundar * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ import matplotlib matplotlib.use('WXAgg') from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg from matplotlib.backends.backend_wxagg import Toolbar from matplotlib.figure import Figure from matplotlib import rc rc('text', usetex=True) import wx import numpy import gastablesgui.Isentropic as Isentropic import gastablesgui.NormalShock as NormalShock import gastablesgui.ObliqueShock as ObliqueShock import gastablesgui.PrandtlMeyer as PrandtlMeyer import gastablesgui.FannoFlow as FannoFlow import gastablesgui.Isothermal as Isothermal import gastablesgui.RayleighFlow as RayleighFlow TITLE = "Gas Tables" ABOUT_TITLE = "About Gas Tables" ABOUT_BODY = "A Graphical Interface for the python gas tables module. \n\nAuthors : \ Varun Hiremath, Venkattraman A, Shyam Sundar C" # Generate IDs for different Menu actions. ID_About = wx.NewId() ID_Exit = wx.NewId() ID_Isentropic = wx.NewId() ID_NormalShock = wx.NewId() ID_ObliqueShock = wx.NewId() ID_FannoFlow = wx.NewId() ID_RayleighFlow = wx.NewId() ID_Isothermal = wx.NewId() ID_PrandtlMeyer = wx.NewId() # colours used in status bar RED = wx.Color(200,100,0) class GasTables(wx.Frame): def __init__(self, parent, ID, title): self.parent = parent self.ID = ID self.title = title self.ModuleName = None self.Plotted = False self.gamma = 1.4 self.initialise() def initialise(self): wx.Frame.__init__(self, self.parent, self.ID, self.title, wx.DefaultPosition, wx.Size(800, 300)) self.CreateStatusBar() self.SetStatusMessage("Please select a Module from the Modules menu.") self.sizer = wx.BoxSizer(wx.VERTICAL) ModulesMenu = wx.Menu() ModulesMenu.Append(ID_Isentropic, "&Isentropic", "Isentropic relations") ModulesMenu.Append(ID_NormalShock, "&NormalShock", "Normal Shock relations") ModulesMenu.Append(ID_ObliqueShock, "&ObliqueShock", "Oblique Shock relations") ModulesMenu.Append(ID_Isothermal, "&Isothermal", "Isothermal relations") ModulesMenu.Append(ID_FannoFlow, "&FannoFlow", "Fanno Flow relations") ModulesMenu.Append(ID_RayleighFlow, "&RayleighFlow", "Rayleigh Flow relations") ModulesMenu.Append(ID_PrandtlMeyer, "&PrandtlMeyer", "Prandtl Meyer relations") ModulesMenu.AppendSeparator() ModulesMenu.Append(ID_Exit, "E&xit", "Terminate the program") HelpMenu = wx.Menu() HelpMenu.Append(ID_About, "&About", "More information about this program") menuBar = wx.MenuBar() menuBar.Append(ModulesMenu, "&Modules") menuBar.Append(HelpMenu, "&Help") self.SetMenuBar(menuBar) wx.EVT_MENU(self, ID_About, self.About ) wx.EVT_MENU(self, ID_Exit, self.Quit ) wx.EVT_MENU(self, ID_Isentropic, self.Isentropic ) wx.EVT_MENU(self, ID_NormalShock , self.NormalShock ) wx.EVT_MENU(self, ID_ObliqueShock, self.ObliqueShock) wx.EVT_MENU(self, ID_FannoFlow , self.FannoFlow ) wx.EVT_MENU(self, ID_RayleighFlow, self.RayleighFlow) wx.EVT_MENU(self, ID_Isothermal , self.Isothermal ) wx.EVT_MENU(self, ID_PrandtlMeyer, self.PrandtlMeyer) def initFigure(self): self.fig = Figure((10,4), dpi=80) self.canvas = FigureCanvas(self, 0, self.fig) self.toolbar = Toolbar(self.canvas) self.toolbar.Realize() self.sizer.Add(self.canvas, 0, wx.BOTTOM, 1) self.sizer.Add(self.toolbar, 0, wx.CENTER|wx.BOTTOM, 1) def Isentropic(self, event, VALUES = None, SECOND_VALUES=None): self.ModuleName = "Isentropic" self.FIELDS = ["M", "M*", "T/To", "P/Po", "A/A*", "r/ro", "F/F*", "AP/A*Po" ] self.createDialog(self.ModuleName, self.FIELDS, self.Isentropic, VALUES, SECOND_VALUES) def NormalShock(self, event, VALUES = None, SECOND_VALUES=None): self.ModuleName = "Normal Shock" self.FIELDS = ["Mx", "My", "Py/Px", "Poy/Px", "Poy/Pox", "ry/rx", "Ty/Tx"] self.createDialog(self.ModuleName, self.FIELDS, self.NormalShock, VALUES, SECOND_VALUES) def ObliqueShock(self, event,VALUES = None, SECOND_VALUES = None): self.ModuleName = "Oblique Shock" self.FIELDS = ["Mx","Turn Angle","Wave Angle","My", "Py/Px", "Poy/Px", "Poy/Pox","ry/rx", "Ty/Tx"] self.createDialog(self.ModuleName, self.FIELDS, self.ObliqueShock, VALUES, SECOND_VALUES, 3, False) def Isothermal(self, event, VALUES = None, SECOND_VALUES=None): self.ModuleName = "Isothermal" self.FIELDS = ["M","P/P*(ref)","r*(ref)/r","To/To*(ref)","Po/Po*(ref)","4fLmax/D"] self.createDialog(self.ModuleName, self.FIELDS, self.Isothermal, VALUES, SECOND_VALUES) def FannoFlow(self, event, VALUES=None, SECOND_VALUES=None): self.ModuleName = "Fanno Flow" self.FIELDS = ["M", "P/Pstar", "T/Tstar", "rho/rhostar", "Po/Postar", "F/Fstar", "4fLmax/D" ] self.createDialog(self.ModuleName, self.FIELDS, self.FannoFlow, VALUES, SECOND_VALUES) def RayleighFlow(self, event, VALUES = None, SECOND_VALUES=None): self.ModuleName = "Rayleigh Flow" self.FIELDS = ["M","P/P*","Po/Po*","T/T*","To/To*","r/r*","Qmax/CpT"] self.createDialog(self.ModuleName, self.FIELDS, self.RayleighFlow, VALUES, SECOND_VALUES) def PrandtlMeyer(self, event, VALUES=None, SECOND_VALUES=None): self.ModuleName = "Prandtl Meyer" self.FIELDS = ["M","Prandtl function","Mach angle"] self.createDialog(self.ModuleName, self.FIELDS, self.PrandtlMeyer, VALUES, SECOND_VALUES, None, False) def createDialog(self, ModuleName, FIELDS, Function, VALUES=None, SECOND_VALUES=None, N=None, Plot=True): self.ModuleName = ModuleName self.CreateStatusBar() self.SetStatusMessage(self.ModuleName + " Running") self.sizer.Clear(True) panel = wx.Panel(self,1) self.FIELDS = FIELDS self.LABELS = {} self.ENTRIES = {} self.VALUES = {} if VALUES == None: for field in self.FIELDS: self.VALUES[field] = "" else: for field in self.FIELDS: self.VALUES[field] = str(round(VALUES[field],4)) if N == None: N = len(self.FIELDS) empty = wx.StaticText(panel, -1, " ") gamma_text = wx.StaticText(panel, 1, "Gamma") self.gamma_value = wx.TextCtrl(panel, -1, str(self.gamma)) fieldSizer = wx.FlexGridSizer(2, len(self.FIELDS)+1, 10, 10) for field in self.FIELDS[:N]: self.LABELS[field] = wx.StaticText(panel, -1, field) self.ENTRIES[field] = wx.TextCtrl(panel, -1, self.VALUES[field]) self.ENTRIES[field].SetToolTipString("Enter the value of %s" % field) for field in self.FIELDS[N:]: self.LABELS[field] = wx.StaticText(panel, -1, field) self.ENTRIES[field] = wx.TextCtrl(panel, -1, self.VALUES[field], style = wx.TE_READONLY) if self.VALUES[field] == "": self.ENTRIES[field].Enable(False) self.ENTRIES[field].SetToolTipString("Enter the value of %s" % field) fieldSizer.Add(gamma_text, 0, wx.LEFT, 2) for field in self.FIELDS: fieldSizer.Add(self.LABELS[field], 0, wx.LEFT, 2) fieldSizer.Add(self.gamma_value) for field in self.FIELDS: fieldSizer.Add(self.ENTRIES[field]) if SECOND_VALUES != None: fieldSizer.Add(empty) for field in self.FIELDS: fieldSizer.Add(wx.TextCtrl(panel, -1, str(round(SECOND_VALUES[field],4)))) calculateButton = wx.Button(panel, -1, "Calculate") resetButton = wx.Button(panel, -1, "Reset") if Plot: plotButton = wx.Button(panel, -1, "Plot") self.plotxOptions = wx.Choice(panel) self.plotyOptions = wx.Choice(panel) self.plotxOptions.AppendItems(strings=self.FIELDS) self.plotyOptions.AppendItems(strings=self.FIELDS) self.plotxOptions.Select(n=0) self.plotyOptions.Select(n=1) self.Bind(wx.EVT_BUTTON, self.readData, calculateButton) self.Bind(wx.EVT_BUTTON, Function, resetButton) if Plot: self.Bind(wx.EVT_BUTTON, self.plotData, plotButton) buttonSizer = wx.FlexGridSizer(1,5,10,5) if Plot: buttonSizer.Add(plotButton) buttonSizer.Add(self.plotxOptions) buttonSizer.Add(self.plotyOptions) buttonSizer.Add(calculateButton) buttonSizer.Add(resetButton) border = wx.BoxSizer(wx.VERTICAL) border.Add(fieldSizer ,0, wx.ALL, 20) border.Add(buttonSizer,0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, 20) panel.SetSizer(border) self.sizer.Add(panel) self.SetSizer(self.sizer) self.Fit() def readData(self, event): VALUES = {} NEW_VALUES = None SECOND_VALUES = None # Read Values for field in self.FIELDS: VALUES[field] = self.ENTRIES[field].GetValue() # Gamma if self.gamma_value.GetValue() != "": self.gamma = float(self.gamma_value.GetValue()) # Do some checks and call the appropriate function if self.ModuleName == "Isentropic": try: if VALUES["M"] != "": NEW_VALUES = Isentropic.get_allValues_from_M(float(VALUES["M"]), self.gamma) elif VALUES["T/To"] != "": NEW_VALUES = Isentropic.get_allValues_from_T_by_To(float(VALUES["T/To"]), self.gamma) elif VALUES["P/Po"] != "": NEW_VALUES = Isentropic.get_allValues_from_P_by_Po(float(VALUES["P/Po"]), self.gamma) elif VALUES["r/ro"] != "": NEW_VALUES = Isentropic.get_allValues_from_rho_by_rhoo(float(VALUES["r/ro"]), self.gamma) elif VALUES["A/A*"] != "": (NEW_VALUES, SECOND_VALUES) = Isentropic.get_allValues_from_A_by_Astar(float(VALUES["A/A*"]), self.gamma) elif VALUES["F/F*"] != "": NEW_VALUES = Isentropic.get_allValues_from_F_by_Fstar(float(VALUES["A/A*"]),self.gamma) elif VALUES["AP/A*Po"] != "": NEW_VALUES = Isentropic.get_allValues_from_A_by_Astar(float(VALUES["AP/A*Po"]),self.gamma) if NEW_VALUES == None: raise Exception("Please enter some value!") else: self.Isentropic(event, NEW_VALUES, SECOND_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) if self.ModuleName == "Normal Shock" : try: if VALUES["Mx"] != "": NEW_VALUES = NormalShock.get_allValues_from_Mx(float(VALUES["Mx"]), self.gamma) elif VALUES["My"] != "": NEW_VALUES = NormalShock.get_allValues_from_My(float(VALUES["My"]), self.gamma) elif VALUES["Py/Px"] != "": NEW_VALUES = NormalShock.get_allValues_from_Py_by_Px(float(VALUES["Py/Px"]), self.gamma) elif VALUES["Poy/Px"] != "": NEW_VALUES = NormalShock.get_allValues_from_Poy_by_Px(float(VALUES["Poy/Px"]), self.gamma) elif VALUES["Poy/Pox"] != "": NEW_VALUES = NormalShock.get_allValues_from_Poy_by_Pox(float(VALUES["Poy/Pox"]), self.gamma) elif VALUES["Ty/Tx"] != "": NEW_VALUES = NormalShock.get_allValues_from_Ty_by_Tx(float(VALUES["Ty/Tx"]),self.gamma) elif VALUES["ry/rx"] != "": NEW_VALUES = NormalShock.get_allValues_from_rhoy_by_rhox(float(VALUES["ry/rx"]),self.gamma) if NEW_VALUES == None: raise Exception("Please enter some value!") else: self.NormalShock(event, NEW_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) if self.ModuleName == "Oblique Shock" : try: if VALUES["Mx"] != "": if VALUES["Turn Angle"] == "" and VALUES["Wave Angle"] == "": raise Exception("Please enter the value of Mx and one of Wave or Turn Angles.") if VALUES["Wave Angle"] != "" : NEW_VALUES, SECOND_VALUES = ObliqueShock.get_allValues_from_Mx_and_Wave_Angle(float(VALUES["Mx"]),float(VALUES["Wave Angle"]),self.gamma) if VALUES["Turn Angle"] != "" : NEW_VALUES, SECOND_VALUES = ObliqueShock.get_allValues_from_Mx_and_Turn_Angle(float(VALUES["Mx"]),float(VALUES["Turn Angle"]),self.gamma) else: raise Exception("Please enter the value of Mx!") self.ObliqueShock(event,NEW_VALUES, SECOND_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) if self.ModuleName == "Prandtl Meyer" : try: if VALUES["M"] != "" : NEW_VALUES = PrandtlMeyer.get_allValues_from_M(float(VALUES["M"]),self.gamma) if VALUES["Prandtl function"] != "" : NEW_VALUES = PrandtlMeyer.get_allValues_from_Prandtl_Func(float(VALUES["Prandtl function"]),self.gamma) if VALUES["Mach angle"] != "" : NEW_VALUES = PrandtlMeyer.get_allValues_from_Mach_Angle(float(VALUES["Mach angle"]),self.gamma) if NEW_VALUES == None: raise Exception("Please enter some value!") else: self.PrandtlMeyer(event,NEW_VALUES, SECOND_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) if self.ModuleName == "Fanno Flow": try: if VALUES["M"] != "": NEW_VALUES = FannoFlow.get_allValues_from_M(float(VALUES["M"]), self.gamma) elif VALUES["P/Pstar"] != "": NEW_VALUES = FannoFlow.get_allValues_from_P_by_Pstar(float(VALUES["P/Pstar"]), self.gamma) elif VALUES["T/Tstar"] != "": NEW_VALUES = FannoFlow.get_allValues_from_T_by_Tstar(float(VALUES["T/Tstar"]), self.gamma) elif VALUES["rho/rhostar"] != "": NEW_VALUES = FannoFlow.get_allValues_from_rho_by_rhostar(float(VALUES["rho/rhostar"]), self.gamma) elif VALUES["Po/Postar"] != "": NEW_VALUES , SECOND_VALUES = FannoFlow.get_allValues_from_Po_by_Postar(float(VALUES["Po/Postar"]), self.gamma) elif VALUES["F/Fstar"] != "": NEW_VALUES,SECOND_VALUES = FannoFlow.get_allValues_from_F_by_Fstar(float(VALUES["F/Fstar"]), self.gamma) elif VALUES["4fLmax/D"] != "": NEW_VALUES ,SECOND_VALUES= FannoFlow.get_allValues_from_4fLmax_by_D(float(VALUES["4fLmax/D"]), self.gamma) if NEW_VALUES == None: raise Exception("Please enter some value!") else: self.FannoFlow(event, NEW_VALUES,SECOND_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) if self.ModuleName == "Isothermal" : try : if VALUES["M"] != "" : NEW_VALUES = Isothermal.get_allValues_from_M(float(VALUES["M"]),self.gamma) elif VALUES["P/P*(ref)"] != "" : NEW_VALUES = Isothermal.get_allValues_from_P_by_Pstarref(float(VALUES["P/P*(ref)"]),self.gamma) elif VALUES["r*(ref)/r"] != "" : NEW_VALUES = Isothermal.get_allValues_from_rhostarref_by_rho(float(VALUES["r*(ref)/r"]),self.gamma) elif VALUES["To/To*(ref)"] != "" : NEW_VALUES = Isothermal.get_allValues_from_To_by_Tostarref(float(VALUES["To/To*(ref)"]),self.gamma) elif VALUES["Po/Po*(ref)"] != "" : NEW_VALUES, SECOND_VALUES = Isothermal.get_allValues_from_Po_by_Postarref(float(VALUES["Po/Po*(ref)"]),self.gamma) elif VALUES["4fLmax/D"] != "" : NEW_VALUES ,SECOND_VALUES= Isothermal.get_allValues_from_4fLmax_by_D(float(VALUES["4fLmax/D"]),self.gamma) if NEW_VALUES == None: raise Exception("Please enter some value!") else: self.Isothermal(event,NEW_VALUES,SECOND_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) if self.ModuleName == "Rayleigh Flow" : try : if VALUES["M"] != "" : NEW_VALUES = RayleighFlow.get_allValues_from_M(float(VALUES["M"]),self.gamma) elif VALUES["P/P*"] != "" : NEW_VALUES = RayleighFlow.get_allValues_from_P_by_Pstar(float(VALUES["P/P*"]),self.gamma) elif VALUES["Po/Po*"] != "": NEW_VALUES, SECOND_VALUES = RayleighFlow.get_allValues_from_Po_by_Postar(float(VALUES["Po/Po*"]),self.gamma) elif VALUES["T/T*"] : NEW_VALUES, SECOND_VALUES = RayleighFlow.get_allValues_from_T_by_Tstar(float(VALUES["T/T*"]),self.gamma) elif VALUES["To/To*"] != "" : NEW_VALUES, SECOND_VALUES = RayleighFlow.get_allValues_from_To_by_Tostar(float(VALUES["To/To*"]),self.gamma) elif VALUES["r/r*"] != "" : NEW_VALUES = RayleighFlow.get_allValues_from_rho_by_rhostar(float(VALUES["r/r*"]),self.gamma) elif VALUES["Qmax/CpT"] != "" : NEW_VALUES = RayleighFlow.get_allValues_from_Qmax_by_CpT(float(VALUES["Qmax/CpT"]),self.gamma) if NEW_VALUES == None: raise Exception("Please enter some value!") else: self.RayleighFlow(event, NEW_VALUES, SECOND_VALUES) except Exception, e: self.SetStatusMessage(str(e[0]), RED) def plotData(self, event): if self.ModuleName == "Isentropic": values = Isentropic.get_plotData_from_M(self.gamma) elif self.ModuleName == "Normal Shock": values = NormalShock.get_plotData_from_Mx(self.gamma) elif self.ModuleName == "Oblique Shock": values = ObliqueShock.get_plotData_from_M(20.0, self.gamma) elif self.ModuleName == "Fanno Flow": values = FannoFlow.get_plotData_from_M(self.gamma) elif self.ModuleName == "Rayleigh Flow" : values = RayleighFlow.get_plotData_from_M(self.gamma) elif self.ModuleName == "Isothermal": values = Isothermal.get_plotData_from_M(self.gamma) if(self.Plotted): try: self.sizer.Remove(self.canvas) self.sizer.Remove(self.toolbar) self.Fit() except: pass self.initFigure() plotArea = self.fig.add_subplot(111) plotArea.set_xlabel(self.FIELDS[self.plotxOptions.GetSelection()]) plotArea.set_ylabel(self.FIELDS[self.plotyOptions.GetSelection()]) plotArea.plot(values[self.FIELDS[self.plotxOptions.GetSelection()]],values[self.FIELDS[self.plotyOptions.GetSelection()]]) self.toolbar.update() self.Fit() self.Plotted = True def About(self, event): self.Alert(ABOUT_TITLE,ABOUT_BODY) def Quit(self, event): self.Close(true) def Alert(self,title,msg): dlg = wx.MessageDialog(self, msg, title, wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def SetStatusMessage(self, message, colour=wx.NullColour): if colour!= wx.NullColour: print message myBar = self.GetStatusBar() myBar.SetBackgroundColour(colour) myBar.SetStatusText(message) self.SetStatusBar(myBar) class GasTablesGUI(wx.App): def OnInit(self): frame = GasTables(None, -1, TITLE) frame.Show(True) self.SetTopWindow(frame) return True app = GasTablesGUI(0) app.MainLoop() gastables/gui/setup.py0000644000175000017500000000070111303442576014374 0ustar varunvarunimport sys from distutils.core import setup setup(name='gastablesgui', version='0.3', description="GUI for python Gas Tables modules for compressible gas flow calculations.", author="Varun Hiremath, Venkattraman A", author_email="varunhiremath@gmail.com", url="http://code.google.com/p/python-gastables/", license='GPL', platforms=['Any'], packages = ['gastablesgui'], scripts = ['gastables']) gastables/gui/AUTHORS0000644000175000017500000000017110765016324013732 0ustar varunvarunVarun Hiremath Venkattraman A C Shyam Sundar gastables/gui/README0000644000175000017500000000147610765016324013553 0ustar varunvarungastables: GUI for python gastable modules for compressible gas flow calculations =================================================================================== NOTATIONS: --------- M - mach number, A - area, P - pressure, T - temperature, rho - density, F - impulse function f - mean coefficient of friction D - hydraulic mean diameter Lmax - maximum pipe length required for choking conditions g = Cp/Cv (ratio of specific heats) (can be set to required value using __init__ while creating the instance of the class) SUBSCRIPTS: ---------- o - Stagnation quantity x - Upstream of shock y - Downstream of shock star - corresponding to choking condition (M = 1) starref - corresponding to M = 1/(sqrt(gamma)) Note: All the angles are in degrees. -- Varun Hiremath , Sun, 9 Mar 2008 23:06:29 +0530 gastables/gui/gastablesgui/0000755000175000017500000000000011303442601015323 5ustar varunvarungastables/gui/gastablesgui/PrandtlMeyer.py0000644000175000017500000000272711303442576020326 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.PrandtlMeyer import PrandtlMeyer def get_allValues_from_M(M,gamma) : pm = PrandtlMeyer(gamma) VALUES = {} VALUES["M"] = M try : VALUES["Prandtl function"] = pm.get_Prandtl_Func_from_M(M) VALUES["Mach angle"] = pm.get_Mach_Angle_from_M(M) return VALUES except Exception, e: raise Exception(e) def get_allValues_from_Prandtl_Func(Prandtl_Func,gamma) : pm = PrandtlMeyer(gamma) try : return get_allValues_from_M(pm.get_M_from_Prandtl_Func(Prandtl_Func),gamma) except Exception, e: raise Exception(e) def get_allValues_from_Mach_Angle(alpha,gamma): pm = PrandtlMeyer(gamma) try : return get_allValues_from_M(pm.get_M_from_Mach_Angle(alpha),gamma) except Exception, e: raise Exception(e) gastables/gui/gastablesgui/Isothermal.py0000644000175000017500000000630011303442576020016 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.Isothermal import Isothermal from scipy import arange def get_allValues_from_M(M,gamma) : iso = Isothermal(gamma) VALUES = {} VALUES["M"] = M VALUES["P/P*(ref)"] = iso.get_P_by_Pstarref_from_M(M) VALUES["r*(ref)/r"] = iso.get_rhostarref_by_rho_from_M(M) VALUES["To/To*(ref)"] = iso.get_To_by_Tostarref_from_M(M) VALUES["Po/Po*(ref)"] = iso.get_Po_by_Postarref_from_M(M) VALUES["4fLmax/D"] = iso.get_4fLmax_by_D_from_M(M) return VALUES def get_allValues_from_P_by_Pstarref(P_by_Pstarref,gamma): iso = Isothermal(gamma) return get_allValues_from_M(iso.get_M_from_P_by_Pstarref(P_by_Pstarref),gamma) def get_allValues_from_rhostarref_by_rho(rhostarref_by_rho,gamma): iso = Isothermal(gamma) return get_allValues_from_M(iso.get_M_from_rhostarref_by_rho(rhostarref_by_rho),gamma) def get_allValues_from_To_by_Tostarref(To_by_Tostarref,gamma): iso = Isothermal(gamma) return get_allValues_from_M(iso.get_M_from_To_by_Tostarref(To_by_Tostarref),gamma) def get_allValues_from_Po_by_Postarref(Po_by_Postarref,gamma): iso = Isothermal(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = iso.get_M_from_Po_by_Postarref(Po_by_Postarref) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_allValues_from_4fLmax_by_D(fLmax_by_D,gamma): iso = Isothermal(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = iso.get_M_from_4fLmax_by_D(fLmax_by_D) #print Mach_Nos if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_plotData_from_M(gamma): MRange = arange(0.1,5.01,0.1) VALUES = {"M" : MRange, "P/P*(ref)" : [], "r*(ref)/r": [], "To/To*(ref)" : [], "Po/Po*(ref)" : [] , "4fLmax/D" : [] } iso = Isothermal(gamma) for M in MRange: VALUES["P/P*(ref)"].append(iso.get_P_by_Pstarref_from_M(M)) VALUES["r*(ref)/r"].append(iso.get_rhostarref_by_rho_from_M(M)) VALUES["To/To*(ref)"].append(iso.get_To_by_Tostarref_from_M(M)) VALUES["Po/Po*(ref)"].append(iso.get_Po_by_Postarref_from_M(M)) VALUES["4fLmax/D"].append(iso.get_4fLmax_by_D_from_M(M)) return VALUES gastables/gui/gastablesgui/gastables0000777000175000017500000000000011303442601023176 2../../modules/gastablesustar varunvarungastables/gui/gastablesgui/__init__.py0000644000175000017500000000000010765136746017447 0ustar varunvarungastables/gui/gastablesgui/ObliqueShock.py0000644000175000017500000000652511303442576020310 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.ObliqueShock import ObliqueShock from scipy import arange def get_allValues_from_Mx_and_Wave_Angle(Mx,Wave_Angle,gamma): os = ObliqueShock(gamma) return get_allValues_from_Mx_and_Turn_Angle(Mx, os.get_Turn_Angle_from_Mx_and_Wave_Angle(Mx,Wave_Angle),gamma) def get_allValues_from_Mx_and_Turn_Angle(Mx,Turn_Angle,gamma): os = ObliqueShock(gamma) VALUES = {} VALUES["Mx"] = Mx VALUES["Turn Angle"] = Turn_Angle VALUES["Wave Angle"] = os.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx,Turn_Angle) VALUES["My"] = os.get_My_from_Mx_and_Turn_Angle(Mx,Turn_Angle) VALUES["Py/Px"] = os.get_Py_by_Px_from_Mx_and_Turn_Angle(Mx,Turn_Angle) VALUES["Ty/Tx"] = os.get_Ty_by_Tx_from_Mx_and_Turn_Angle(Mx,Turn_Angle) VALUES["ry/rx"] = os.get_rhoy_by_rhox_from_Mx_and_Turn_Angle(Mx,Turn_Angle) VALUES["Poy/Px"] = os.get_Poy_by_Px_from_Mx_and_Turn_Angle(Mx,Turn_Angle) VALUES["Poy/Pox"] = os.get_Poy_by_Pox_from_Mx_and_Turn_Angle(Mx,Turn_Angle) SECOND_VALUES = {} SECOND_VALUES["Mx"] = Mx SECOND_VALUES["Turn Angle"] = Turn_Angle SECOND_VALUES["Wave Angle"] = os.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) SECOND_VALUES["My"] = os.get_My_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) SECOND_VALUES["Py/Px"] = os.get_Py_by_Px_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) SECOND_VALUES["Ty/Tx"] = os.get_Ty_by_Tx_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) SECOND_VALUES["ry/rx"] = os.get_rhoy_by_rhox_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) SECOND_VALUES["Poy/Px"] = os.get_Poy_by_Px_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) SECOND_VALUES["Poy/Pox"] = os.get_Poy_by_Pox_from_Mx_and_Turn_Angle(Mx,Turn_Angle, True) return VALUES, SECOND_VALUES def get_plotData_from_M(Mx,gamma): Wave_Angle_Range = arange(10,80.01,0.1) VALUES = {"Mx" : Mx, "Turn Angle" : [],"Wave Angle" : Wave_Angle_Range, "My" : [], "Py/Px" : [], "Poy/Px" : [], "Poy/Pox" : [],"ry/rx" : [] , "Ty/Tx" : []} os = ObliqueShock(gamma) for Wave_Angle in Wave_Angle_Range: Turn_Angle = os.get_Turn_Angle_from_Mx_and_Wave_Angle(Mx,Wave_Angle) VALUES["Turn Angle"].append(Turn_Angle) VALUES["My"].append(os.get_My_from_Mx_and_Turn_Angle(Mx,Turn_Angle)) VALUES["Py/Px"].append(os.get_Py_by_Px_from_Mx_and_Turn_Angle(Mx,Turn_Angle)) VALUES["Ty/Tx"].append(os.get_Ty_by_Tx_from_Mx_and_Turn_Angle(Mx,Turn_Angle)) VALUES["ry/rx"].append(os.get_rhoy_by_rhox_from_Mx_and_Turn_Angle(Mx,Turn_Angle)) VALUES["Poy/Px"].append(os.get_Poy_by_Px_from_Mx_and_Turn_Angle(Mx,Turn_Angle)) VALUES["Poy/Pox"].append(os.get_Poy_by_Pox_from_Mx_and_Turn_Angle(Mx,Turn_Angle)) return VALUES gastables/gui/gastablesgui/FannoFlow.py0000644000175000017500000000714611303442576017611 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.FannoFlow import FannoFlow from scipy import arange def get_allValues_from_M(M, gamma): fanno = FannoFlow(gamma) VALUES = {} VALUES["M"] = M VALUES["P/Pstar"] = fanno.get_P_by_Pstar_from_M(M) VALUES["T/Tstar"] = fanno.get_T_by_Tstar_from_M(M) VALUES["rho/rhostar"] = fanno.get_rho_by_rhostar_from_M(M) VALUES["Po/Postar"] = fanno.get_Po_by_Postar_from_M(M) VALUES["F/Fstar"] = fanno.get_F_by_Fstar_from_M(M) VALUES["4fLmax/D"] = fanno.get_4fLmax_by_D_from_M(M) return VALUES def get_allValues_from_P_by_Pstar(P_by_Pstar,gamma): fanno = FannoFlow(gamma) return get_allValues_from_M(fanno.get_M_from_P_by_Pstar(P_by_Pstar),gamma) def get_allValues_from_rho_by_rhostar(rho_by_rhostar,gamma): fanno = FannoFlow(gamma) return get_allValues_from_M(fanno.get_M_from_rho_by_rhostar(rho_by_rhostar),gamma) def get_allValues_from_T_by_Tstar(T_by_Tstar,gamma): fanno = FannoFlow(gamma) return get_allValues_from_M(fanno.get_M_from_T_by_Tstar(T_by_Tstar),gamma) def get_allValues_from_Po_by_Postar(Po_by_Postar,gamma): fanno = FannoFlow(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = fanno.get_M_from_Po_by_Postar(Po_by_Postar) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_allValues_from_F_by_Fstar(F_by_Fstar,gamma): fanno = FannoFlow(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = fanno.get_M_from_F_by_Fstar(F_by_Fstar) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_allValues_from_4fLmax_by_D(temp,gamma): fanno = FannoFlow(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = fanno.get_M_from_4fLmax_by_D(temp) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_plotData_from_M(gamma): MRange = arange(0.1,5.01,0.1) VALUES = {"M" : MRange, "P/Pstar" : [], "rho/rhostar": [], "T/Tstar" : [], "Po/Postar" : [], "F/Fstar" : [], "4fLmax/D" : [] } fanno = FannoFlow(gamma) for M in MRange: VALUES["P/Pstar"].append(fanno.get_P_by_Pstar_from_M(M)) VALUES["T/Tstar"].append(fanno.get_T_by_Tstar_from_M(M)) VALUES["rho/rhostar"].append(fanno.get_rho_by_rhostar_from_M(M)) VALUES["Po/Postar"].append(fanno.get_Po_by_Postar_from_M(M)) VALUES["F/Fstar"].append(fanno.get_F_by_Fstar_from_M(M)) VALUES["4fLmax/D"].append(fanno.get_4fLmax_by_D_from_M(M)) return VALUES gastables/gui/gastablesgui/NormalShock.py0000644000175000017500000000622611303442576020136 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.NormalShock import NormalShock from scipy import arange def get_allValues_from_Mx(Mx,gamma) : ns = NormalShock(gamma) VALUES = {} VALUES["Mx"] = Mx try: VALUES["My"] = ns.get_My_from_Mx(Mx) VALUES["Py/Px"] = ns.get_Py_by_Px_from_Mx(Mx) VALUES["Poy/Px"] = ns.get_Poy_by_Px_from_Mx(Mx) VALUES["Poy/Pox"] = ns.get_Poy_by_Pox_from_Mx(Mx) VALUES["ry/rx"] = ns.get_rhoy_by_rhox_from_Mx(Mx) VALUES["Ty/Tx"] = ns.get_Ty_by_Tx_from_Mx(Mx) return VALUES except Exception, e: raise Exception(e) def get_allValues_from_My(My,gamma): ns = NormalShock(gamma) try: return get_allValues_from_Mx(ns.get_Mx_from_My(My), gamma) except Exception, e: raise Exception(e) def get_allValues_from_Py_by_Px(Py_by_Px,gamma): ns = NormalShock(gamma) try: return get_allValues_from_Mx(ns.get_Mx_from_Py_by_Px(Py_by_Px), gamma) except Exception, e: raise Exception(e) def get_allValues_from_Poy_by_Px(Poy_by_Px,gamma): ns = NormalShock(gamma) try: return get_allValues_from_Mx(ns.get_Mx_from_Poy_by_Px(Poy_by_Px) ,gamma) except Exception, e: raise Exception(e) def get_allValues_from_Poy_by_Pox(Poy_by_Pox,gamma): ns = NormalShock(gamma) try: Mx = ns.get_Mx_from_Poy_by_Pox(Poy_by_Pox) return get_allValues_from_Mx(Mx, gamma) except Exception, e: raise Exception(e) def get_allValues_from_rhoy_by_rhox(rhoy_by_rhox,gamma): ns = NormalShock(gamma) try: return get_allValues_from_Mx(ns.get_Mx_from_rhoy_by_rhox(rhoy_by_rhox), gamma) except Exception, e: raise Exception(e) def get_allValues_from_Ty_by_Tx(Ty_by_Tx,gamma): ns = NormalShock(gamma) try: return get_allValues_from_Mx(ns.get_Mx_from_Ty_by_Tx(Ty_by_Tx), gamma) except Exception, e: raise Exception(e) def get_plotData_from_Mx(gamma): MxRange = arange(1.01,10.01,0.1) VALUES = {"Mx" : MxRange, "My" : [], "Py/Px": [], "Poy/Px" : [], "Poy/Pox" : [], "ry/rx" : [], "Ty/Tx" : [] } ns = NormalShock(gamma) for Mx in MxRange: VALUES["My"].append(ns.get_My_from_Mx(Mx)) VALUES["Py/Px"].append(ns.get_Py_by_Px_from_Mx(Mx)) VALUES["Poy/Px"].append(ns.get_Poy_by_Px_from_Mx(Mx)) VALUES["Poy/Pox"].append(ns.get_Poy_by_Pox_from_Mx(Mx)) VALUES["ry/rx"].append(ns.get_rhoy_by_rhox_from_Mx(Mx)) VALUES["Ty/Tx"].append(ns.get_Ty_by_Tx_from_Mx(Mx)) return VALUES gastables/gui/gastablesgui/Isentropic.py0000644000175000017500000000543111303442576020032 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.Isentropic import Isentropic from scipy import arange def get_allValues_from_M(M, gamma): isen = Isentropic(gamma) VALUES = {} VALUES["M"] = M VALUES["M*"] = isen.get_Mstar_from_M(M) VALUES["T/To"] = isen.get_T_by_To_from_M(M) VALUES["P/Po"] = isen.get_P_by_Po_from_M(M) VALUES["A/A*"] = isen.get_A_by_Astar_from_M(M) VALUES["r/ro"] = isen.get_rho_by_rhoo_from_M(M) VALUES["F/F*"] = isen.get_F_by_Fstar_from_M(M) VALUES["AP/A*Po"] = isen.get_AP_by_AstarPo_from_M(M) return VALUES def get_allValues_from_T_by_To(T_by_To, gamma): isen = Isentropic(gamma) return get_allValues_from_M(isen.get_M_from_T_by_To(T_by_To), gamma) def get_allValues_from_P_by_Po(P_by_Po, gamma): isen = Isentropic(gamma) return get_allValues_from_M(isen.get_M_from_P_by_Po(P_by_Po), gamma) def get_allValues_from_rho_by_rhoo(rho_by_rhoo, gamma): isen = Isentropic(gamma) return get_allValues_from_M(isen.get_M_from_rho_by_rhoo(rho_by_rhoo), gamma) def get_allValues_from_A_by_Astar(A_by_Astar, gamma): isen = Isentropic(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = isen.get_M_from_A_by_Astar(A_by_Astar) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_plotData_from_M(gamma): MRange = arange(0.1,5.01,0.1) VALUES = {"M" : MRange, "M*" : [], "T/To": [], "P/Po" : [], "A/A*" : [], "r/ro" : [], "F/F*" : [], "AP/A*Po" : []} isen = Isentropic(gamma) for M in MRange: VALUES["M*"].append(isen.get_Mstar_from_M(M)) VALUES["T/To"].append(isen.get_T_by_To_from_M(M)) VALUES["P/Po"].append(isen.get_P_by_Po_from_M(M)) VALUES["A/A*"].append(isen.get_A_by_Astar_from_M(M)) VALUES["r/ro"].append(isen.get_rho_by_rhoo_from_M(M)) VALUES["F/F*"].append(isen.get_F_by_Fstar_from_M(M)) VALUES["AP/A*Po"].append(isen.get_AP_by_AstarPo_from_M(M)) return VALUES gastables/gui/gastablesgui/RayleighFlow.py0000644000175000017500000000766211303442576020317 0ustar varunvarun""" * Copyright (C) 2008 Varun Hiremath. * Copyright (C) 2008 A Venkattraman. * Copyright (C) 2008 C Shyam Sundar. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A, Shyam Sundar C """ from gastables.RayleighFlow import RayleighFlow from scipy import arange def get_allValues_from_M(M,gamma) : rf = RayleighFlow(gamma) VALUES = {} VALUES["M"] = M try : VALUES["P/P*"] = rf.get_P_by_Pstar_from_M(M) VALUES["Po/Po*"] = rf.get_Po_by_Postar_from_M(M) VALUES["T/T*"] = rf.get_T_by_Tstar_from_M(M) VALUES["To/To*"] = rf.get_To_by_Tostar_from_M(M) VALUES["r/r*"] = rf.get_rho_by_rhostar_from_M(M) VALUES["Qmax/CpT"] = rf.get_Qmax_by_CpT_from_M(M) return VALUES except Exception, e: raise Exception(e) def get_allValues_from_P_by_Pstar(P_by_Pstar,gamma): rf = RayleighFlow(gamma) try: return get_allValues_from_M(rf.get_M_from_P_by_Pstar(P_by_Pstar),gamma) except Exception,e: raise Exception(e) def get_allValues_from_Po_by_Postar(Po_by_Postar,gamma): rf = RayleighFlow(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = rf.get_M_from_Po_by_Postar(Po_by_Postar) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_allValues_from_T_by_Tstar(T_by_Tstar,gamma): rf = RayleighFlow(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = rf.get_M_from_T_by_Tstar(T_by_Tstar) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_allValues_from_To_by_Tostar(To_by_Tostar,gamma): rf = RayleighFlow(gamma) rf = RayleighFlow(gamma) VALUES = {} SECOND_VALUES = None Mach_Nos = rf.get_M_from_To_by_Tostar(To_by_Tostar) if(type(Mach_Nos) == tuple): M1 = Mach_Nos[0] M2 = Mach_Nos[1] VALUES = get_allValues_from_M(M1, gamma) SECOND_VALUES = get_allValues_from_M(M2, gamma) else: VALUES = get_allValues_from_M(Mach_Nos, gamma) return VALUES, SECOND_VALUES def get_allValues_from_rho_by_rhostar(rho_by_rhostar,gamma): rf = RayleighFlow(gamma) try: return get_allValues_from_M(rf.get_M_from_rho_by_rhostar(rho_by_rhostar),gamma) except Exception,e: raise Exception(e) def get_allValues_from_Qmax_by_CpT(Qmax_by_CpT,gamma) : rf = RayleighFlow(gamma) try: return get_allValues_from_M(rf.get_M_from_Qmax_by_CpT(Qmax_by_CpT),gamma) except Exception,e: raise Exception(e) def get_plotData_from_M(gamma): MRange = arange(0.01,10.01,0.1) VALUES = {"M" : MRange, "P/P*" :[], "Po/Po*" :[], "T/T*":[], "To/To*":[], "r/r*":[],"Qmax/CpT":[]} rf = RayleighFlow(gamma) for M in MRange : VALUES["P/P*"].append(rf.get_P_by_Pstar_from_M(M)) VALUES["Po/Po*"].append(rf.get_Po_by_Postar_from_M(M)) VALUES["T/T*"].append(rf.get_T_by_Tstar_from_M(M)) VALUES["To/To*"].append(rf.get_To_by_Tostar_from_M(M)) VALUES["r/r*"].append(rf.get_rho_by_rhostar_from_M(M)) VALUES["Qmax/CpT"].append(rf.get_Qmax_by_CpT_from_M(M)) return VALUES gastables/gui/COPYING0000644000175000017500000004311010765015063013714 0ustar varunvarun GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gastables/modules/0000755000175000017500000000000011303442602013536 5ustar varunvarungastables/modules/PKG-INFO0000644000175000017500000000102010765016400014630 0ustar varunvarunName: gastables Version: 0.2 Summary: compressible flow gas table modules for python Home-page: http://code.google.com/p/python-gastables/ Author: Varun Hiremath, Venkattraman A License: GPL Description: Gas Tables include modules for compressible gas flow calculations. The main modules currently included are: - Isentropic Relations - Normal Shock Relations - Oblique Shock Relations - Fanno Flow - Isothermal Flow - Rayleigh Flow - Prandtl Meyer Function . Homepage: http://code.google.com/p/python-gastables/ gastables/modules/gastables/0000755000175000017500000000000011303442602015503 5ustar varunvarungastables/modules/gastables/PrandtlMeyer.py0000644000175000017500000000345210765015400020472 0ustar varunvarun""" Python module for Prandtl Meyer functions with Mach angles Assumptions: 1) Perfect gas with constant specific heats and molecular weights 2) Isentropic flow """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from scipy import optimize from math import * class PrandtlMeyer: def __init__(self, g=1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = g def get_Prandtl_Func_from_M(self, M): """ Returns Prandtl Meyer function (degrees) corresponding to the given Mach No. """ return (sqrt((self.g+1)/(self.g-1))* atan(sqrt((self.g-1)/(self.g+1)*(M**2 - 1))) - atan(sqrt(M**2 -1)))*180.0/pi def get_Mach_Angle_from_M(self, M): """ Returns Mach Angle (degrees) for a given Mach No. M """ return asin(1.0/M)*180.0/pi def get_M_from_Prandtl_Func(self, omega): """ Returns Mach No. corresponding to the given Prandtl function value omega (degrees) """ return optimize.fsolve(lambda M: self.get_Prandtl_Func_from_M(M) - omega, 1.01) def get_M_from_Mach_Angle(self, alpha): """ Returns Mach No. corresponding to the given Mach Angle alpha (degrees)""" alpha = alpha*pi/180.0 return 1.0/sin(alpha) gastables/modules/gastables/Isothermal.py0000644000175000017500000003240410765015400020172 0ustar varunvarun""" Python module for isothermal flow of perfect gases with friction The combined effect of friction and heat transfer in long ducts can be condidered to isothermal flow model. Here the reference value of the properties (p*, rho*,c*,To*,po* and Lmax) are taken at the Mach number M* = 1/sqrt(gamma) Assumptions: 1) One dimensional flow with friction and heat transfer 2) Constant area duct 3) Perfect gas with constant specific heat and Molecular weights 4) Isothermal flow """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from math import * from scipy import optimize class Isothermal: def __init__(self, g = 1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = 1.4 def get_P_by_Pstarref_from_M(self,M): """ Returns the value of p/p* at Mach number M """ if M <= 0: raise Exception('Value of M negative or zero . M should be greater than zero') return else: return 1.0/self.g**(0.5)/M def get_rhostarref_by_rho_from_M(self,M): """ Returns the value of rho*/rho at Mach number M """ if M <= 0: raise Exception('Value of M negative or zero . M should be greater than zero') return else: return self.g**(0.5)*M def get_To_by_Tostarref_from_M(self,M) : """ Returns the value of To/To* at Mach number M """ if M <= 0: raise Exception('Value of M negative or zero . M should be greater than zero') return else: return 2.0*self.g/(3*self.g-1)*(1+(self.g-1)/2*M**2) def get_Po_by_Postarref_from_M(self,M): """ Returns the value of po/po* at Mach number M """ if M <= 0: raise Exception('Value of M negative or zero . M should be greater than zero') return else: return 1.0/sqrt(self.g)/M*(2.0*self.g/(3.0*self.g-1)*(1+(self.g-1)/2*M**2))**(self.g/(self.g-1)) def get_4fLmax_by_D_from_M(self,M): """ Returns the value of 4f*(Lmax/D) at Mach number M """ if M <= 0: raise Exception('Value of M negative or zero . M should be greater than zero') return else: return (1-self.g*M**2)/self.g/M**2 + log(self.g*M**2) def get_M_from_P_by_Pstarref(self,P_by_Pstarref): """ Returns Mach number at p/p* equal to P_by_Pstarref """ if P_by_Pstarref<= 0 or P_by_Pstarref > 10000: raise Exception('Value of P_by_Pstarref should be greater than zero and less than 10000') return else: return 1.0/P_by_Pstarref/sqrt(self.g) def get_rhostarref_by_rho_from_P_by_Pstarref(self,P_by_Pstarref): """Returns rho*/rho at p/p* equal to P_by_Pstarref""" if P_by_Pstarref<= 0 or P_by_Pstarref > 10000: raise Exception('Value of P_by_Pstarref should be greater than zero and less than 10000') return else: M = self.get_M_from_P_by_Pstarref(P_by_Pstarref) return self.get_rhostarref_by_rho_from_M(M) def get_To_by_Tostarref_from_P_by_Pstarref(self,P_by_Pstarref) : """Returns To/To* at p/p* equal to P_by_Pstarref""" if P_by_Pstarref<= 0 or P_by_Pstarref > 10000: raise Exception('Value of P_by_Pstarref should be greater than zero and less than 10000') return else: M = self.get_M_from_P_by_Pstarref(P_by_Pstarref) return self.get_To_by_Tostarref_from_M(M) def get_Po_by_Postarref_from_P_by_Pstarref(self,P_by_Pstarref): """Returns Po/Po* at p/p* equal to P_by_Pstarref""" if P_by_Pstarref<= 0 or P_by_Pstarref > 10000: raise Exception('Value of P_by_Pstarref should be greater than zero and less than 10000') return else: M = self.get_M_from_P_by_Pstarref(P_by_Pstarref) return self.get_Po_by_Postarref_from_M(M) def get_4fLmax_by_D_from_P_by_Pstarref(self,P_by_Pstarref): """Returns 4f*Lmax/D at p/p* equal to P_by_Pstarref""" if P_by_Pstarref<= 0 or P_by_Pstarref > 10000: raise Exception('Value of P_by_Pstarref should be greater than zero and less than 10000') return else: M = self.get_M_from_P_by_Pstarref(P_by_Pstarref) return self.get_4fLmax_by_D_from_M(M) def get_M_from_rhostarref_by_rho(self,rhostarref_by_rho): """ Returns Mach number at rho*/rho equal to rhostarref_by_rho """ if rhostarref_by_rho<= 0.0001 or rhostarref_by_rho > 11000: raise Exception('Value of rhostarref/rho should be greater than 0.0001 and less than 11000') return else: return rhostarref_by_rho/sqrt(self.g) def get_P_by_Pstarref_from_rhostarref_by_rho(self,rhostarref_by_rho): """ Returns p/p* at rho*/rho equal to rhostarref_by_rho """ if rhostarref_by_rho<= 0.0001 or rhostarref_by_rho > 11000: raise Exception('Value of rhostarref/rho should be greater than 0.0001 and less than 11000') return else: M = self.get_M_from_rhostarref_by_rho(rhostarref_by_rho) return self.get_P_by_Pstarref_from_M(M) def get_To_by_Tostarref_from_rhostarref_by_rho(self,rhostarref_by_rho) : """ Returns To/To* at rho*/rho equal to rhostarref_by_rho """ if rhostarref_by_rho<= 0.0001 or rhostarref_by_rho > 11000: raise Exception('Value of rhostarref/rho should be greater than 0.0001 and less than 11000') return else: M = self.get_M_from_rhostarref_by_rho(rhostarref_by_rho) return self.get_To_by_Tostarref_from_M(M) def get_Po_by_Postarref_from_rhostarref_by_rho(self,rhostarref_by_rho): """ Returns po/po* at rho*/rho equal to rhostarref_by_rho """ if rhostarref_by_rho<= 0.0001 or rhostarref_by_rho > 11000: raise Exception('Value of rhostarref/rho should be greater than 0.0001 and less than 11000') return else: M = self.get_M_from_rhostarref_by_rho(rhostarref_by_rho) return self.get_Po_by_Postarref_from_M(M) def get_4fLmax_by_D_from_rhostarref_by_rho(self,rhostarref_by_rho): """ Returns 4f*Lmax/D at rho*/rho equal to rhostarref_by_rho """ if rhostarref_by_rho<= 0.0001 or rhostarref_by_rho > 11000: raise Exception('Value of rhostarref/rho should be greater than 0.0001 and less than 11000') return else: M = self.get_M_from_rhostarref_by_rho(rhostarref_by_rho) return self.get_4fLmax_by_D_from_M(M) def get_M_from_To_by_Tostarref(self,To_by_Tostarref): """ Returns Mach number at To/To* equal to To_by_Tostarref """ if To_by_Tostarref<= 0.875 or To_by_Tostarref > 17500000: raise Exception('Value of To_by_Tostarref should be greater than 0.875 and less than 17500000') return else: return (((3*self.g-1)/2/self.g*To_by_Tostarref-1)*2/(self.g-1))**0.5 def get_P_by_Pstarref_from_To_by_Tostarref(self,To_by_Tostarref): """ Returns p/p* at To/To* equal to To_by_Tostarref """ if To_by_Tostarref<= 0.875 or To_by_Tostarref > 17500000: raise Exception('Value of To_by_Tostarref should be greater than 0.875 and less than 17500000') return else: M = self.get_M_from_To_by_Tostarref(To_by_Tostarref) return self.get_P_by_Pstarref_from_M(M) def get_rhostarref_by_rho_from_To_by_Tostarref(self,To_by_Tostarref): """ Returns rho*/rho at To/To* equal to To_by_Tostarref """ if To_by_Tostarref<= 0.875 or To_by_Tostarref > 17500000: raise Exception('Value of To_by_Tostarref should be greater than 0.875 and less than 17500000') return else: M = self.get_M_from_To_by_Tostarref(To_by_Tostarref) return self.get_rhostarref_by_rho_from_M(M) def get_Po_by_Postarref_from_To_by_Tostarref(self,To_by_Tostarref): """ Returns po/po* at To/To* equal to To_by_Tostarref """ if To_by_Tostarref<= 0.875 or To_by_Tostarref > 17500000: raise Exception('Value of To_by_Tostarref should be greater than 0.875 and less than 17500000') return else: M = self.get_M_from_To_by_Tostarref(To_by_Tostarref) return self.get_Po_by_Postarref_from_M(M) def get_4fLmax_by_D_from_To_by_Tostarref(self,To_by_Tostarref): """ Returns 4f*Lmax/D at To/To* equal to To_by_Tostarref """ if To_by_Tostarref<= 0.875 or To_by_Tostarref > 17500000: raise Exception('Value of To_by_Tostarref should be greater than 0.875 and less than 17500000') return else: M = self.get_M_from_To_by_Tostarref(To_by_Tostarref) return self.get_4fLmax_by_D_from_M(M) def get_M_from_Po_by_Postarref(self,Po_by_Postarref): """ Returns Mach number at po/po* equal to Po_by_Postarref """ #return (optimize.bisect(lambda M : self.get_Po_by_Postarref_from_M(M) - Po_by_Postarref, 0.001 , 1.0/sqrt(self.g)), optimize.bisect(lambda M : self.get_Po_by_Postarref_from_M(M) - Po_by_Postarref, 1.0/(sqrt(self.g), 100.0))) if Po_by_Postarref<= 1.9 or Po_by_Postarref > 5290: raise Exception('Value of Po_by_Postarref should be greater than 1.9 and less than 5290') return else: return (optimize.bisect(lambda M : self.get_Po_by_Postarref_from_M(M) - Po_by_Postarref, 0.001 , 1.0), optimize.bisect(lambda M : self.get_Po_by_Postarref_from_M(M) - Po_by_Postarref, 1.0, 100.0)) def get_P_by_Pstarref_from_Po_by_Postarref(self,Po_by_Postarref): """ Returns p/p* at po/po* equal to Po_by_Postarref """ if Po_by_Postarref<= 1.9 or Po_by_Postarref > 5290: raise Exception('Value of Po_by_Postarref should be greater than 1.9 and less than 5290') return else: M = self.get_M_from_Po_by_Postarref(Po_by_Postarref) return (self.get_P_by_Pstarref_from_M(M[0]),self.get_P_by_Pstarref_from_M(M[1])) def get_rhostarref_by_rho_from_Po_by_Postarref(self,Po_by_Postarref): """ Returns rho*/rho at po/po* equal to Po_by_Postarref """ if Po_by_Postarref<= 1.9 or Po_by_Postarref > 5290: raise Exception('Value of Po_by_Postarref should be greater than 1.9 and less than 5290') return else: M = self.get_M_from_Po_by_Postarref(Po_by_Postarref) return (self.get_rhostarref_by_rho_from_M(M[0]),self.get_rhostarref_by_rho_from_M(M[1])) def get_To_by_Tostarref_from_Po_by_Postarref(self,Po_by_Postarref) : """ Returns To/To* at po/po* equal to Po_by_Postarref """ if Po_by_Postarref<= 1.9 or Po_by_Postarref > 5290: raise Exception('Value of Po_by_Postarref should be greater than 1.9 and less than 5290') return else: M = self.get_M_from_Po_by_Postarref(Po_by_Postarref) return (self.get_To_by_Tostarref_from_M(M[0]),self.get_To_by_Tostarref_from_M(M[1])) def get_4fLmax_by_D_from_Po_by_Postarref(self,Po_by_Postarref): """ Returns 4f*Lmax/D at po/po* equal to Po_by_Postarref """ if Po_by_Postarref<= 1.9 or Po_by_Postarref > 5290: raise Exception('Value of Po_by_Postarref should be greater than 1.9 and less than 5290') return else: M = self.get_M_from_Po_by_Postarref(Po_by_Postarref) return (self.get_4fLmax_by_D_from_M(M[0]),self.get_4fLmax_by_D_from_M(M[1])) def get_M_from_4fLmax_by_D(self,fLmax_by_D): """ Returns Mach number at 4f*(Lmax/D) equal to fLmax_by_D """ if fLmax_by_D<= 17 or fLmax_by_D > 71428552: raise Exception('Value of 4fLmax_by_D should be greater than 17 and less than 71428552') return else: return (optimize.bisect(lambda M : self.get_4fLmax_by_D_from_M(M) - fLmax_by_D, 0.001, 1.0/sqrt(self.g)+0.001), optimize.bisect(lambda M : self.get_4fLmax_by_D_from_M(M ) - fLmax_by_D, 1.0/sqrt(self.g)-0.001, 100.0)) def get_P_by_Pstarref_from_4fLmax_by_D(self,fLmax_by_D): """ Returns p/p* at 4f*(Lmax/D) equal to fLmax_by_D """ if fLmax_by_D<= 17 or fLmax_by_D > 71428552: raise Exception('Value of 4fLmax_by_D should be greater than 17 and less than 71428552') return else: M = self.get_M_from_4fLmax_by_D(fLmax_by_D) return (self.get_P_by_Pstarref_from_M(M[0]),self.get_P_by_Pstarref_from_M(M[1])) def get_rhostarref_by_rho_from_4fLmax_by_D(self,fLmax_by_D): """ Returns rho*/rho at 4f*(Lmax/D) equal to fLmax_by_D """ if fLmax_by_D<= 17 or fLmax_by_D > 71428552: raise Exception('Value of 4fLmax_by_D should be greater than 17 and less than 71428552') return else: M = self.get_M_from_4fLmax_by_D(fLmax_by_D) return (self.get_rhostarref_by_rho_from_M(M[0]),self.get_rhostarref_by_rho_from_M(M[1])) def get_To_by_Tostarref_from_4fLmax_by_D(self,fLmax_by_D) : """ Returns To/To* at 4f*(Lmax/D) equal to fLmax_by_D """ if fLmax_by_D<= 17 or fLmax_by_D > 71428552: raise Exception('Value of 4fLmax_by_D should be greater than 17 and less than 71428552') return else: M = self.get_M_from_4fLmax_by_D(fLmax_by_D) return (self.get_To_by_Tostarref_from_M(M[0]),self.get_To_by_Tostarref_from_M(M[1])) def get_Po_by_Postarref_from_4fLmax_by_D(self,fLmax_by_D): """ Returns po/po* at 4f*(Lmax/D) equal to fLmax_by_D """ if fLmax_by_D<= 17 or fLmax_by_D > 71428552: raise Exception('Value of 4fLmax_by_D should be greater than 17 and less than 71428552') return else: M = self.get_M_from_4fLmax_by_D(fLmax_by_D) return (self.get_Po_by_Postarref_from_M(M[0]),self.get_Po_by_Postarref_from_M(M[1])) gastables/modules/gastables/__init__.py0000644000175000017500000000000310732170652017615 0ustar varunvarun gastables/modules/gastables/ObliqueShock.py0000644000175000017500000001345610765015400020461 0ustar varunvarun""" Python module for properties behind an oblique shock in perfect gases An Oblique shock wave is inclined at an angle to the direction of upstream flow. Supersonic flow passing through an oblique shock (wave angle = beta) is deflected through an angle (delta). Assumptions: 1) Perfect gas with constant specific heats and molecular weights 2) Adiabatic flow 3) Absence of body forces 4) Absence of external work """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from scipy import optimize from math import * from NormalShock import NormalShock class ObliqueShock: def __init__(self, g = 1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = g self.NS = NormalShock(self.g) def get_Turn_Angle_from_Mx_and_Wave_Angle(self, Mx, beta): """Returns turn angle (degrees) from Mx and wave angle beta (degrees)""" beta = beta * pi/180 if Mx < 1: raise Exception('The value of Mx should be greater than 1') return else : return atan(2/tan(beta)*(Mx**2 * sin(beta)**2 - 1)/(Mx**2 *(self.g + cos(2*beta)) + 2)) * 180/pi def get_Wave_Angle_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns wave angle (degrees) from Mx and turn angle theta (degrees) for a weak shock. Pass True as the third argument for strong shock.""" if Strong: return optimize.fsolve(lambda beta:self.get_Turn_Angle_from_Mx_and_Wave_Angle(Mx, beta) - theta, 80.0) else: return optimize.fsolve(lambda beta:self.get_Turn_Angle_from_Mx_and_Wave_Angle(Mx, beta) - theta, 10.0) def get_My_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns My from Mx and turn angle theta (degrees) for a weak shock. Pass True as the third argument for strong shock.""" beta = self.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx, theta, Strong) beta = beta * pi/180 theta = theta * pi/180 M1n = Mx * sin(beta) M2n = self.NS.get_My_from_Mx(M1n) return M2n / sin(beta - theta) def get_Py_by_Px_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns py/px from Mx and turn angle theta (degrees) for a weak shock. Pass True as the third argument for strong shock.""" beta = self.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx , theta, Strong) beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Py_by_Px_from_Mx(M1n) def get_Py_by_Px_from_Mx_and_Wave_Angle(self, Mx, beta): """Returns py/px from Mx and wave angle beta (degrees)""" beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Py_by_Px_from_Mx(M1n) def get_Ty_by_Tx_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns Ty/Tx from Mx and turn angle theta (degrees) for a weak shock. Pass True as the third argument for strong shock.""" beta = self.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx , theta, Strong) beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Ty_by_Tx_from_Mx(M1n) def get_Ty_by_Tx_from_Mx_and_Wave_Angle(self, Mx, beta): """Returns Ty/Tx from Mx and wave angle equal to beta""" beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Ty_by_Tx_from_Mx(M1n) def get_rhoy_by_rhox_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns rhoy/rhox from Mx and turn angle equal to theta for a weak shock. Pass True as the third argument for strong shock.""" beta = self.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx , theta, Strong) beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_rhoy_by_rhox_from_Mx(M1n) def get_rhoy_by_rhox_from_Mx_and_Wave_Angle(self, Mx, beta): """Returns rhoy/rhox from Mx and wave angle equal to beta""" beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_rhoy_by_rhox_from_Mx(M1n) def get_Poy_by_Pox_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns poy/pox from Mx and turn angle equal to theta for a weak shock. Pass True as the third argument for strong shock.""" beta = self.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx , theta, Strong) beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Poy_by_Pox_from_Mx(M1n) def get_Poy_by_Pox_from_Mx_and_Wave_Angle(self, Mx, beta): """Returns poy/pox from Mx and wave angle equal to beta""" beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Poy_by_Pox_from_Mx(M1n) def get_Poy_by_Px_from_Mx_and_Turn_Angle(self, Mx, theta, Strong=False): """Returns poy/pox from Mx and turn angle equal to theta for a weak shock. Pass True as the third argument for strong shock.""" beta = self.get_Wave_Angle_from_Mx_and_Turn_Angle(Mx , theta, Strong) beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Poy_by_Px_from_Mx(M1n) def get_Poy_by_Px_from_Mx_and_Wave_Angle(self, Mx, beta): """Returns poy/px from Mx and wave angle equal to beta""" beta = beta * pi/180 M1n = Mx * sin(beta) return self.NS.get_Poy_by_Px_from_Mx(M1n) gastables/modules/gastables/FannoFlow.py0000644000175000017500000001543710765015400017763 0ustar varunvarun"""Python module for flow properties of perfect gases with friction In Fanno flow, friction in the passage leads to increase in entropy and takes the process towards the choking conditions, (M = M* = 1). Assumptions: 1) One dimensional flow with friction 2) Constant area duct 3) perfect gas with constant specific heats and molecular weights 4) adiabatic flow """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from scipy import optimize from math import * class FannoFlow : def __init__(self, g= 1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = g def get_P_by_Pstar_from_M(self,M): if M < 0: raise Exception('Value of M negative. M value should be positive') else: return ((self.g+1)/2/(1+ (self.g -1)/ 2*M**2))**(0.5)/M def get_rho_by_rhostar_from_M(self,M): if M < 0: raise Exception('Value of M negative. M value should be positive') else: return ((self.g+1)/2/(1+ (self.g -1)/ 2*M**2))**(0.5)*M def get_T_by_Tstar_from_M(self,M): if M < 0: raise Exception('Value of M negative. M value should be positive') else: return (self.g+1)/2/(1+ (self.g -1)/ 2*M**2) def get_Po_by_Postar_from_M(self,M): if M < 0: raise Exception('Value of M negative. M value should be positive') else: return (2*(1+(self.g-1)/2*M**2)/(self.g+1))**((self.g+1)/(self.g-1)/2)/M def get_F_by_Fstar_from_M(self,M): if M < 0: raise Exception('Value of M negative. M value should be positive') else: return (1+self.g*M**2)/M/(2*(self.g+1)*(1+(self.g-1)/2*M**2))**0.5 def get_4fLmax_by_D_from_M(self,M): if M < 0: raise Exception('Value of M negative. M value should be positive') else: return (1-M**2)/self.g/M**2 + (self.g+1)/2/self.g*log((self.g+1)*M**2/2/(1+(self.g-1)/2*M**2)) def get_M_from_P_by_Pstar(self,P_by_Pstar): if P_by_Pstar <= 0 or P_by_Pstar > self.get_P_by_Pstar_from_M(0.0001): raise Exception('Value of P/Pstar should be greater than 0 and less than %s' % self.get_P_by_Pstar_from_M(0.0001)) else: return optimize.fsolve(lambda M : self.get_P_by_Pstar_from_M(M) - P_by_Pstar, 0.001) def get_rho_by_rhostar_from_P_by_Pstar(self,P_by_Pstar): M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_rho_by_rhostar_from_M(M) def get_T_by_Tstar_from_P_by_Pstar(self,P_by_Pstar): M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_T_by_Tstar_from_M(M) def get_Po_by_Postar_from_P_by_Pstar(self,P_by_Pstar): M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_Po_by_Postar_from_M(M) def get_F_by_Fstar_from_P_by_Pstar(self,P_by_Pstar): M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_F_by_Fstar_from_M(M) def get_4fLmax_by_D_from_P_by_Pstar(self,P_by_Pstar): M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_4fLmax_by_D_from_M(M) def get_M_from_rho_by_rhostar(self,rho_by_rhostar): if rho_by_rhostar <= 0 or rho_by_rhostar > self.get_rho_by_rhostar_from_M(100.0): raise Exception('Value of rho/rhostar should be greater than 0 and less than %s' % self.get_rho_by_rhostar_from_M(100.0)) else: return optimize.fsolve(lambda M : self.get_rho_by_rhostar_from_M(M) - rho_by_rhostar, 0.001) def get_P_by_Pstar_from_rho_by_rhostar(self,rho_by_rhostar): M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_P_by_Pstar_from_M(M) def get_T_by_Tstar_from_rho_by_rhostar(self,rho_by_rhostar): M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_T_by_Tstar_from_M(M) def get_Po_by_Postar_from_rho_by_rhostar(self,rho_by_rhostar): M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_Po_by_Postar_from_M(M) def get_F_by_Fstar_from_rho_by_rhostar(self,rho_by_rhostar): M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_F_by_Fstar_from_M(M) def get_4fLmax_by_D_from_rho_by_rhostar(self,rho_by_rhostar): M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_4fLmax_by_D_from_M(M) def get_M_from_T_by_Tstar(self,T_by_Tstar): if T_by_Tstar > self.get_T_by_Tstar_from_M(0.0001): raise Exception("Value of T/T* should be less than %s" % self.get_T_by_Tstar_from_M(0.0001)) else: return optimize.fsolve(lambda M : self.get_T_by_Tstar_from_M(M) - T_by_Tstar, 0.0001) def get_P_by_Pstar_from_T_by_Tstar(self,T_by_Tstar): M = self.get_M_from_T_by_Tstar(T_by_Tstar) return self.get_P_by_Pstar_from_M(M) def get_rho_by_rhostar_from_T_by_Tstar(self,T_by_Tstar): M = self.get_M_from_T_by_Tstar(T_by_Tstar) return self.get_rho_by_rhostar_from_M(M) def get_Po_by_Postar_from_T_by_Tstar(self,T_by_Tstar): M = self.get_M_from_T_by_Tstar(T_by_Tstar) return self.get_Po_By_Postar_from_M(M) def get_F_by_Fstar_from_T_by_Tstar(self,T_by_Tstar): M = self.get_M_from_T_by_Tstar(T_by_Tstar) return self.get_F_by_Fstar_from_M(M) def get_4fLmax_by_D_from_T_by_Tstar(self,T_by_Tstar): M = self.get_M_from_T_by_Tstar(T_by_Tstar) return self.get_4fLmax_by_D_from_M(M) def get_M_from_Po_by_Postar(self,Po_by_Postar): return (optimize.bisect(lambda M : self.get_Po_by_Postar_from_M(M) - Po_by_Postar, 0.001, 1.0),optimize.bisect(lambda M : self.get_Po_by_Postar_from_M(M) - Po_by_Postar, 1.0, 100)) def get_M_from_F_by_Fstar(self,F_by_Fstar): return (optimize.bisect(lambda M : self.get_F_by_Fstar_from_M(M) - F_by_Fstar, 0.001, 1.0),optimize.bisect(lambda M : self.get_F_by_Fstar_from_M(M) - F_by_Fstar, 1.0, 100)) def get_M_from_4fLmax_by_D(self,fLmax_by_D): return (optimize.bisect(lambda M : self.get_4fLmax_by_D_from_M(M) - fLmax_by_D, 0.001, 1.0),optimize.bisect(lambda M : self.get_4fLmax_by_D_from_M(M) - fLmax_by_D, 1.0, 100)) gastables/modules/gastables/NormalShock.py0000644000175000017500000003405410765015400020306 0ustar varunvarun""" Python module for properties across a normal shock in perfect gases Assumptions: 1) One dimensional flow 2) Constant area duct 3) Perfect gas with constant specific heat and molecular weights 4) Adiabatic flow """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from scipy import optimize from math import * from Isentropic import Isentropic class NormalShock: def __init__(self, g=1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = 1.4 self.Isentropic = Isentropic(self.g) def get_My_from_Mx(self, Mx): """Returns Mach No My behind a normal shock from Mach No Mx ahead of the shock""" if Mx <= 1: raise Exception("Mach No ahead of ths shock Mx should be greater than 1") else: return sqrt((2/(self.g-1) + Mx**2)/(2*self.g/(self.g-1)*Mx**2 -1)) def get_Py_by_Px_from_Mx(self, Mx): """Returns py/px across a normal shock from Mx """ if Mx <= 1: raise Exception("Mach No ahead of ths shock Mx should be greater than 1") else: return 2*self.g/(self.g+1)* Mx**2 - (self.g-1)/(self.g+1) def get_Ty_by_Tx_from_Mx(self, Mx): """Returns Ty/Tx across a normal shock from Mx """ if Mx <= 1: raise Exception("Mach No ahead of ths shock Mx should be greater than 1") else: return (1 + (self.g-1)*0.5* Mx**2)*(2*self.g/(self.g-1)*Mx**2 - 1)/((self.g+1)**2/(self.g-1)*0.5* Mx**2) def get_rhoy_by_rhox_from_Mx(self, Mx): """Returns rhoy/rhox across a normal shock from Mx""" if Mx <= 1: raise Exception("Mach No ahead of ths shock Mx should be greater than 1") else: return self.get_Py_by_Px_from_Mx(Mx) / self.get_Ty_by_Tx_from_Mx(Mx) def get_Poy_by_Pox_from_Mx(self, Mx): """Returns poy/pox across a normal shock from Mx""" if Mx <= 1: raise Exception("Mach No ahead of ths shock Mx should be greater than 1") else: My = self.get_My_from_Mx(Mx) return self.Isentropic.get_P_by_Po_from_M(Mx) * self.get_Py_by_Px_from_Mx(Mx) / self.Isentropic.get_P_by_Po_from_M(My) def get_Poy_by_Px_from_Mx(self, Mx): """Returns poy/px across a normal shock from Mx""" if Mx <= 1: raise Exception("Mach No ahead of ths shock Mx should be greater than 1") else: My = self.get_My_from_Mx(Mx) return self.get_Py_by_Px_from_Mx(Mx) / self.Isentropic.get_P_by_Po_from_M(My) def get_Mx_from_My(self, My): """Returns Mach No Mx ahead of a normal shock from Mach No My behind the shock""" if My >= 1.0 or My <= sqrt((self.g-1)/self.g * 0.5): raise Exception("Mach No behind a normal shock My should be between %s and 1.0" % str(sqrt((self.g-1)/self.g * 0.5))) else: return sqrt((1 + (self.g-1)* 0.5 * My**2)/(self.g * My**2 - (self.g-1)*0.5)) def get_Py_by_Px_from_My(self, My): """Returns py/px across a normal shock from My """ if My >= 1.0 or My <= sqrt((self.g-1)/self.g * 0.5): raise Exception("Mach No behind a normal shock My should be between %s and 1.0" % str(sqrt((self.g-1)/self.g * 0.5))) else : Mx = self.get_Mx_from_My(My) return self.get_Py_by_Px_from_Mx(Mx) def get_Ty_by_Tx_from_My(self, My): """Returns Ty/Tx across a normal shock from My """ if My >= 1.0 or My <= sqrt((self.g-1)/self.g * 0.5): raise Exception("Mach No behind a normal shock My should be between %s and 1.0" % str(sqrt((self.g-1)/self.g * 0.5))) else : Mx = self.get_Mx_from_My(My) return self.get_Ty_by_Tx_from_Mx(Mx) def get_rhoy_by_rhox_from_My(self, My): """Returns rhoy/rhox across a normal shock from My""" if My >= 1.0 or My <= sqrt((self.g-1)/self.g * 0.5): raise Exception("Mach No behind a normal shock My should be between %s and 1.0" % str(sqrt((self.g-1)/self.g * 0.5))) else : Mx = self.get_Mx_from_My(My) return self.get_rhoy_by_rhox_from_Mx(Mx) def get_Poy_by_Pox_from_My(self, My): """Returns poy/pox across a normal shock from My""" if My >= 1.0 or My <= sqrt((self.g-1)/self.g * 0.5): raise Exception("Mach No behind a normal shock My should be between %s and 1.0" % str(sqrt((self.g-1)/self.g * 0.5))) else : Mx = self.get_Mx_from_My(My) return self.get_Poy_by_Pox_from_Mx(Mx) def get_Poy_by_Px_from_My(self, My): """Returns poy/px across a normal shock from My""" if My >= 1.0 or My <= sqrt((self.g-1)/self.g * 0.5): raise Exception("Mach No behind a normal shock My should be between %s and 1.0" % str(sqrt((self.g-1)/self.g * 0.5))) else : Mx = self.get_Mx_from_My(My) return self.get_Poy_by_Px_from_Mx(Mx) def get_Mx_from_Ty_by_Tx(self, Ty_by_Tx): """Returns Mx from Ty/Tx equal to Ty_by_Tx""" if Ty_by_Tx <= 1.0: raise Exception("Ty/Tx must be greater than 1") else: a = 2*self.g*(self.g-1) b = 4*self.g - (self.g-1)**2 - Ty_by_Tx * (self.g+1)**2 c = -2*(self.g-1) return sqrt((-b + sqrt(b**2 - 4*a*c))/a *0.5) def get_My_from_Ty_by_Tx(Self, Ty_by_Tx): """Returns Mx from Ty/Tx equal to Ty_by_Tx""" if Ty_by_Tx <= 1.0: raise Exception("Ty/Tx must be greater than 1") else: Mx = self.get_Mx_from_Ty_by_Tx(Ty_by_Tx) return self.get_My_from_Mx(Mx) def get_Py_by_Px_from_Ty_by_Tx(self, Ty_by_Tx): """Returns Py/Px from Ty/Tx equal to Ty_by_Tx""" if Ty_by_Tx <= 1.0: raise Exception("Ty/Tx must be greater than 1") else: Mx = self.get_Mx_from_Ty_by_Tx(Ty_by_Tx) return self.get_Py_by_Px_from_Mx(Mx) def get_Poy_by_Pox_from_Ty_by_Tx(self, Ty_by_Tx): """Returns poy/pox from Ty/Tx equal to Ty_by_Tx""" if Ty_by_Tx <= 1.0: raise Exception("Ty/Tx must be greater than 1") else: Mx = self.get_Mx_from_Ty_by_Tx(Ty_by_Tx) return self.get_Poy_by_Pox_from_Mx(Mx) def get_Poy_by_Px_from_Ty_by_Tx(self, Ty_by_Tx): """Returns poy/px from Ty/Tx equal to Ty_by_Tx""" if Ty_by_Tx <= 1.0: raise Exception("Ty/Tx must be greater than 1") else: Mx = self.get_Mx_from_Ty_by_Tx(Ty_by_Tx) return self.get_Poy_by_Px_from_Mx(Mx) def get_Mx_from_Py_by_Px(self, Py_by_Px): """Returns Mx from py/px equal to Py_by_Px""" if Py_by_Px <= 1: raise Exception("py/px must be greater than 1") else: return sqrt((Py_by_Px - 1)* (self.g+1)/self.g * 0.5 + 1) def get_My_from_Py_by_Px(self, Py_by_Px): """Returns My from py/px equal to Py_by_Px""" if Py_by_Px <= 1: raise Exception("py/px must be greater than 1") else: Mx = self.get_Mx_from_Py_by_Px(Py_by_Px) return self.get_My_from_Mx(Mx) def get_Ty_by_Tx_from_Py_by_Px(self, Py_by_Px): """Returns Ty/Tx from py/px equal to Py_by_Px""" if Py_by_Px <= 1: raise Exception("py/px must be greater than 1") else: Mx = self.get_Mx_from_Py_by_Px(Py_by_Px) return self.get_Ty_by_Tx_from_Mx(Mx) def get_Poy_by_Pox_from_Py_by_Px(self, Py_by_Px): """Returns poy/pox from Py/Px equal to Py_by_Px""" if Py_by_Px <= 1: raise Exception("py/px must be greater than 1") else: Mx = self.get_Mx_from_Py_by_Px(Py_by_Px) return self.get_Poy_by_Pox_from_Mx(Mx) def get_Poy_by_Px_from_Py_by_Px(self, Py_by_Px): """Returns Poy/Px from Py/Px equal to Py_by_Px""" if Py_by_Px <= 1: raise Exception("py/px must be greater than 1") else: Mx = self.get_Mx_from_Py_by_Px(Py_by_Px) return self.get_Poy_by_Px_from_Mx(Mx) def get_Mx_from_rhoy_by_rhox(self, rhoy_by_rhox): """Returns Mx from rhoy/rhox equal to rhoy_by_rhox""" if rhoy_by_rhox <=1.0 or rhoy_by_rhox >= (self.g+1)/(self.g-1): raise Exception("rhoy/rhox should be between 1 and ",(self.g+1)/(self.g-1)) else: return sqrt(2*rhoy_by_rhox/(self.g+1- rhoy_by_rhox*(self.g-1))) def get_My_from_rhoy_by_rhox(self, rhoy_by_rhox): """Returns My from rhoy/rhox equal to rhoy_by_rhox""" if rhoy_by_rhox <=1.0 or rhoy_by_rhox >= (self.g+1)/(self.g-1): raise Exception("rhoy/rhox should be between 1 and ",(self.g+1)/(self.g-1)) else: Mx = self.get_Mx_from_rhoy_by_rhox(rhoy_by_rhox) return self.get_My_from_Mx(Mx) def get_Ty_by_Tx_from_rhoy_by_rhox(self, rhoy_by_rhox): """Returns Ty/Tx from rhoy/rhox equal to rhoy_by_rhox""" if rhoy_by_rhox <=1.0 or rhoy_by_rhox >= (self.g+1)/(self.g-1): raise Exception("rhoy/rhox should be between 1 and ",(self.g+1)/(self.g-1)) else: Mx = self.get_Mx_from_rhoy_by_rhox(rhoy_by_rhox) return self.get_Ty_by_Tx_from_Mx(Mx) def get_Poy_by_Pox_from_rhoy_by_rhox(self, rhoy_by_rhox): """Returns poy/pox from rhoy/rhox equal to rhoy_by_rhox""" if rhoy_by_rhox <=1.0 or rhoy_by_rhox >= (self.g+1)/(self.g-1): raise Exception("rhoy/rhox should be between 1 and ",(self.g+1)/(self.g-1)) else: Mx = self.get_Mx_from_rhoy_by_rhox(rhoy_by_rhox) return self.get_Poy_by_Pox_from_Mx(Mx) def get_Poy_by_Px_from_rhoy_by_rhox(self, rhoy_by_rhox): """Returns poy/px from rhoy/rhox equal to rhoy_by_rhox""" if rhoy_by_rhox <=1.0 or rhoy_by_rhox >= (self.g+1)/(self.g-1): raise Exception("rhoy/rhox should be between 1 and ",(self.g+1)/(self.g-1)) else: Mx = self.get_Mx_from_rhoy_by_rhox(rhoy_by_rhox) return self.get_Poy_by_Px_from_Mx(Mx) def get_Mx_from_Poy_by_Pox(self, Poy_by_Pox): """Returns Mx from poy/pox equal to Poy_by_Pox""" if Poy_by_Pox <= 0 or Poy_by_Pox >= 1: raise Exception("Poy/Pox must be between 0 and 1") else: return optimize.fsolve(lambda Mx: self.get_Poy_by_Pox_from_Mx(Mx) - Poy_by_Pox, 2.0) def get_My_from_Poy_by_Pox(self, Poy_by_Pox): """Returns My from poy/pox equal to Poy_by_Pox""" if Poy_by_Pox <= 0 or Poy_by_Pox >= 1: raise Exception("Poy/Pox must be between 0 and 1") else: Mx = self.get_Mx_from_Poy_by_Pox(Poy_by_Pox) return self.get_My_from_Mx(Mx) def get_Ty_by_Tx_from_Poy_by_Pox(self, Poy_by_Pox): """Returns Ty/Tx from poy/pox equal to Poy_by_Pox""" if Poy_by_Pox <= 0 or Poy_by_Pox >= 1: raise Exception("Poy/Pox must be between 0 and 1") else: Mx = self.get_Mx_from_Poy_by_Pox(Poy_by_Pox) return self.get_Ty_by_Tx_from_Mx(Mx) def get_Py_by_Px_from_Poy_by_Pox(self, Poy_by_Pox): """Returns py/px from poy/pox equal to Poy_by_Pox""" if Poy_by_Pox <= 0 or Poy_by_Pox >= 1: raise Exception("Poy/Pox must be between 0 and 1") else: Mx = self.get_Mx_from_Poy_by_Pox(Poy_by_Pox) return self.get_Py_by_Px_from_Mx(Mx) def get_Poy_by_Px_from_Poy_by_Pox(self, Poy_by_Pox): """Returns poy/px from poy/pox equal to Poy_by_Pox""" if Poy_by_Pox <= 0 or Poy_by_Pox >= 1: raise Exception("Poy/Pox must be between 0 and 1") else: Mx = self.get_Mx_from_Poy_by_Pox(Poy_by_Pox) return self.get_Poy_by_Px_from_Mx(Mx) def get_Mx_from_Poy_by_Px(self, Poy_by_Px): """Returns Mx from poy/px equal to Poy_by_Px""" if Poy_by_Px <= ((self.g+1)*0.5)**(self.g/(self.g-1)): raise Exception("Poy/Px should be greater than",((self.g+1)*0.5)**(self.g/(self.g-1))) else: return optimize.fsolve(lambda Mx: self.get_Poy_by_Px_from_Mx(Mx) - Poy_by_Px, 2.0) def get_My_from_Poy_by_Px(self, Poy_by_Px): """Returns My from poy/px equal to Poy_by_Px""" if Poy_by_Px <= ((self.g+1)*0.5)**(self.g/(self.g-1)): raise Exception("Poy/Px should be greater than",((self.g+1)*0.5)**(self.g/(self.g-1))) else: Mx = self.get_Mx_from_Poy_by_Px(Poy_by_Px) return self.get_My_from_Mx(Mx) def get_Ty_by_Tx_from_Poy_by_Px(self, Poy_by_Px): """Returns Mx from poy/px equal to Poy_by_Px""" if Poy_by_Px <= ((self.g+1)*0.5)**(self.g/(self.g-1)): raise Exception("Poy/Px should be greater than",((self.g+1)*0.5)**(self.g/(self.g-1))) else: Mx = self.get_Mx_from_Poy_by_Px(Poy_by_Px) return self.get_Ty_by_Tx_from_Mx(Mx) def get_Py_by_Px_from_Poy_by_Px(self, Poy_by_Px): """Returns py/px from poy/px equal to Poy_Px""" if Poy_by_Px <= ((self.g+1)*0.5)**(self.g/(self.g-1)): raise Exception("Poy/Px should be greater than",((self.g+1)*0.5)**(self.g/(self.g-1))) else: Mx = self.get_Mx_from_Poy_by_Px(Poy_by_Px) return self.get_Py_by_Px_from_Mx(Mx) def get_Poy_by_Pox_from_Poy_by_Px(self, Poy_by_Px): """Returns poy/pox from poy/px equal to Poy_by_Px """ if Poy_by_Px <= ((self.g+1)*0.5)**(self.g/(self.g-1)): raise Exception("Poy/Px should be greater than",((self.g+1)*0.5)**(self.g/(self.g-1))) else: Mx = self.get_Mx_from_Poy_by_Px(Poy_by_Px) return self.get_Poy_by_Pox_from_Mx(Mx) gastables/modules/gastables/Isentropic.py0000644000175000017500000002277210765015400020211 0ustar varunvarun""" Python module for isentropic flow properties Assumptions: 1) One dimensional isentropic flow 2) Perfect gas with constant specific heats and molecular weights """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from scipy import optimize from math import * class Isentropic: def __init__(self, g=1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = g def get_T_by_To_from_M(self, M): """Returns the value of T/To at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return 1/(1 + (self.g-1)*0.5*M**2) def get_P_by_Po_from_M(self, M): """Returns the value of p/po at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return (1 + (self.g -1 )*0.5*M**2)**(self.g/(1-self.g)) def get_rho_by_rhoo_from_M(self, M): """Returns the value of rho/rhoo at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return (1 + (self.g -1 )*0.5*M**2)**(1/(1-self.g)) def get_Mstar_from_M(self, M): """Returns the value of M* at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return sqrt(((self.g+1)*0.5*M**2)/(1 + (self.g-1)*0.5*M**2)) def get_A_by_Astar_from_M(self, M): """Returns the value of A/A* at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return 1.0/M*(2/(self.g+1)*(1+(self.g-1)*0.5*M**2))**((self.g+1)/(self.g-1)*0.5) def get_F_by_Fstar_from_M(self, M): """Returns the value of F/F* at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return (1 + self.g*M**2)/(M * sqrt(2*(self.g+1)*(1+(self.g-1)*0.5 * M**2))) def get_AP_by_AstarPo_from_M(self, M): """Returns the value of Ap/A*po at Mach number M""" if M < 0: raise Exception('Value of M negative. M value should be positive') return else: return ((2/(self.g+1))**((self.g+1)/(self.g-1)*0.5))/(M * sqrt(1 + (self.g-1)*0.5 * M**2)) def get_M_from_T_by_To(self, T_by_To): """Returns the value of M at T/To equal to T_by_To""" if T_by_To <= 0.0 or T_by_To >= 1.0: raise Exception("T/T0 must be between 0 and 1") return else: return sqrt(2*((1/T_by_To)-1)/(self.g-1)) def get_P_by_Po_from_T_by_To(self, T_by_To): """Returns the value of p/po at T/To equal to T_by_To""" if T_by_To <= 0.0 or T_by_To >= 1.0: raise Exception("T/T0 must be between 0 and 1") return else: M = self.get_M_from_T_by_To(T_by_To) return self.get_P_by_Po_from_M(M) def get_rho_by_rhoo_from_T_by_To(self, T_by_To): """Returns the value of rho/rhoo at T/To equal to T_by_To""" if T_by_To <= 0.0 or T_by_To >= 1.0: raise Exception("T/T0 must be between 0 and 1") return else: M = self.get_M_from_T_by_To(T_by_To) return self.get_rho_by_rhoo_from_M(M) def get_A_by_Astar_from_T_by_To(self, T_by_To): """Returns the value of A/A* at T/To equal to T_by_To""" if T_by_To <= 0.0 or T_by_To >= 1.0: raise Exception("T/T0 must be between 0 and 1") return else: M = self.get_M_from_T_by_To(T_by_To) return self.get_A_by_Astar_from_M(M) def get_F_by_Fstar_from_T_by_To(self, T_by_To): """Returns the value of F/F* at T/To equal to T_by_To""" if T_by_To <= 0.0 or T_by_To >= 1.0: raise Exception("T/T0 must be between 0 and 1") return else: M = self.get_M_from_T_by_To(T_by_To) return self.get_A_by_Astar_from_M(M) def get_AP_by_AstarPo_from_T_by_To(self, T_by_To): """Returns the value of Ap/A*po at T/To equal to T_by_To""" if T_by_To <= 0.0 or T_by_To >= 1.0: raise Exception("T/T0 must be between 0 and 1") return else: M = self.get_M_from_T_by_To(T_by_To) return self.get_AP_by_AstarP0_from_M(M) def get_M_from_P_by_Po(self, P_by_Po): """Returns the value of M at p/po equal to P_by_Po""" if P_by_Po <= 0.0 or P_by_Po >= 1.0: raise Exception("p/p0 must be between 0 and 1") return else: return sqrt(2*((1/((P_by_Po)**((self.g-1)/self.g)))-1)/(self.g-1)) def get_T_by_To_from_P_by_Po(self, P_by_Po): """Returns the value of T/To at p/po equal to P_by_Po""" if P_by_Po <= 0.0 or P_by_Po >= 1.0: raise Exception("p/p0 must be between 0 and 1") return else: M = self.get_M_from_P_by_Po(P_by_Po) return self.get_T_by_To_from_M(M) def get_rho_by_rhoo_from_P_by_Po(self, P_by_Po): """Returns the value of rho/rhoo at p/po equal to P_by_Po""" if P_by_Po <= 0.0 or P_by_Po >= 1.0: raise Exception("p/p0 must be between 0 and 1") return else: M = self.get_M_from_P_by_Po(P_by_Po) return self.get_rho_by_rhoo_from_M(M) def get_A_by_Astar_from_P_by_Po(self, P_by_Po): """Returns the value of A/A* at p/po equal to P_by_Po""" if P_by_Po <= 0.0 or P_by_Po >= 1.0: raise Exception("p/p0 must be between 0 and 1") return else: M = self.get_M_from_P_by_Po(P_by_Po) return self.get_A_by_Astar_from_M(M) def get_F_by_Fstar_from_P_by_Po(self, P_by_Po): """Returns the value of F/F* at p/po equal to P_by_Po""" if P_by_Po <= 0.0 or P_by_Po >= 1.0: raise Exception("p/p0 must be between 0 and 1") return else: M = self.get_M_from_P_by_Po(P_by_Po) return self.get_F_by_Fstar_from_M(M) def get_AP_by_AstarPo_from_P_by_Po(self, P_by_Po): """Returns the value of Ap/A*po at p/po equal to P_by_Po""" if P_by_Po <= 0.0 or P_by_Po >= 1.0: raise Exception("p/p0 must be between 0 and 1") return else: M = self.get_M_from_P_by_Po(P_by_Po) return self.get_AP_by_AstarPo_from_M(M) def get_M_from_rho_by_rhoo(self, rho_by_rhoo): """Returns the value of M at rho/rhoo equal to rho_by_rhoo""" if rho_by_rhoo <= 0.0 or rho_by_rhoo >= 1.0: raise Exception("rho/rho0 must be between 0 and 1") return else: return sqrt(2.*((1./(rho_by_rhoo**(self.g-1)))-1)/(self.g-1)) def get_T_by_To_from_rho_by_rhoo(self, rho_by_rhoo): """Returns the value of T/To at rho/rhoo equal to rho_by_rhoo""" if rho_by_rhoo <= 0.0 or rho_by_rhoo >= 1.0: raise Exception("rho/rho0 must be between 0 and 1") return else: M = self.get_M_from_rho_by_rhoo(rho_by_rhoo) return self.get_T_by_To_from_M(M) def get_P_by_Po_from_rho_by_rhoo(self, rho_by_rhoo): """Returns the value of p/po at rho/rhoo equal to rho_by_rhoo""" if rho_by_rhoo <= 0.0 or rho_by_rhoo >= 1.0: raise Exception("rho/rho0 must be between 0 and 1") return else: M = self.get_M_from_rho_by_rhoo(rho_by_rhoo) return self.get_P_by_Po_from_M(M) def get_A_by_Astar_from_rho_by_rhoo(self, rho_by_rhoo): """Returns the value of A/A* at rho/rhoo equal to rho_by_rhoo""" if rho_by_rhoo <= 0.0 or rho_by_rhoo >= 1.0: raise Exception("rho/rho0 must be between 0 and 1") return else: M = self.get_M_from_rho_by_rhoo(rho_by_rhoo) return self.get_A_by_Astar_from_M(M) def get_F_by_Fstar_from_rho_by_rhoo(self, rho_by_rhoo): """Returns the value of F/F* at rho/rhoo equal to rho_by_rhoo""" if rho_by_rhoo <= 0.0 or rho_by_rhoo >= 1.0: raise Exception("rho/rho0 must be between 0 and 1") return else: M = self.get_M_from_rho_by_rhoo(rho_by_rhoo) return self.get_F_by_Fstar_from_M(M) def get_M_from_A_by_Astar(self, A_by_Astar): """Returns the two values of M possible(subsonic and supersonic) at A/A* equal to A_by_Astar""" if A_by_Astar < 1.0: raise Exception("A/A* must be greater than 1") return elif A_by_Astar == 1: return 1.0 else: return (optimize.bisect(lambda M: self.get_A_by_Astar_from_M(M)-A_by_Astar, 0.001, 1.0), optimize.bisect(lambda M: self.get_A_by_Astar_from_M(M) - A_by_Astar, 1.0, 100)) gastables/modules/gastables/RayleighFlow.py0000644000175000017500000002545210765015400020464 0ustar varunvarun""" Python module for flow properties of perfect gases with heat transfer In Rayleigh flow, heat addition increases the entropy and takes the process towards the choking conditions, (M = M* = 1). This behaviour imposes a limit to heat addition, therefore for a given initial Mach number there is a fixed value of the maximum possible heat transfer (Qmax). Assumptions: 1) One dimensional flow with Heat transfer 2) Constant area duct 3) Perfect gas with constant specific heats and molecular weights """ """ * Copyright (C) 2006 Varun Hiremath. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Authors: Varun Hiremath, Venkattraman A * Version 0.2 """ from scipy import optimize from math import * class RayleighFlow : def __init__(self, g= 1.4): """ g is the value of gamma (ratio of specific heats), default = 1.4 """ self.g = g def get_P_by_Pstar_from_M(self, M): """Returns the value of p/p* at Mach number M""" return (1+self.g)/(1+self.g*M**2) def get_Po_by_Postar_from_M(self, M): """Returns the value of po/po* at Mach number M""" return (1+self.g)/(1+self.g*M**2)*(2*(1+(self.g-1)/2*M**2)/(self.g+1))**(self.g/(self.g-1)) def get_T_by_Tstar_from_M(self, M): """Returns the value of T/T* at Mach number M""" return ((1+self.g)/(1+self.g*M**2))**2*M**2 def get_To_by_Tostar_from_M(self, M): """Returns the value of To/To* at Mach number M""" return 2*(1+self.g)*M**2*(1+(self.g-1)/2*M**2)/(1+self.g*M**2)**2 def get_rho_by_rhostar_from_M(self, M): """Returns the value of rho/rho* at Mach number M""" return (1+self.g*M**2)/(1+self.g)/M**2 def get_Qmax_by_CpT_from_M(self, M): """Returns the value of Qmax/CpT* at Mach number M""" return (M**2-1)**2/2/(self.g+1)/M**2 def get_M_from_P_by_Pstar(self, P_by_Pstar): """Returns Mach number M at p/p* equal to P_by_Pstar""" if P_by_Pstar > self.get_P_by_Pstar_from_M(0.0001) : raise Exception('Value of P/P* should be greater than 0 and less than %s' % self.get_P_by_Pstar_from_M(0.0001)) else: return (((1+self.g)/P_by_Pstar-1)/self.g)**0.5 def get_Po_by_Postar_from_P_by_Pstar(self, P_by_Pstar): """Returns po/po* at p/p* equal to P_by_Pstar""" M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_Po_by_Postar_from_M(M) def get_T_by_Tstar_from_P_by_Pstar(self, P_by_Pstar): """Returns T/T* at p/p* equal to P_by_Pstar""" M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_T_by_Tstar_from_M(M) def get_To_by_Tostar_from_P_by_Pstar(self, P_by_Pstar): """Returns To/To* at p/p* equal to P_by_Pstar""" M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_To_by_Tostar_from_M(M) def get_rho_by_rhostar_from_P_by_Pstar(self, P_by_Pstar): """Returns rho/rho* at p/p* equal to P_by_Pstar""" M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_rho_by_rhostar_from_M(M) def get_Qmax_by_CpT_from_P_by_Pstar(self, P_by_Pstar): """Returns Qmax/CpT at p/p* equal to P_by_Pstar""" M = self.get_M_from_P_by_Pstar(P_by_Pstar) return self.get_Qmax_by_CpT_from_M(M) def get_M_from_Po_by_Postar(self, Po_by_Postar): """Returns Mach number M at po/po* equal to Po_by_Postar""" if Po_by_Postar < 1.0: raise Exception('Value of Po/Po* should be greater than 1') else: if Po_by_Postar < self.get_Po_by_Postar_from_M(0.001): return (optimize.bisect(lambda M : self.get_Po_by_Postar_from_M(M) - Po_by_Postar, 0.001, 1.0),optimize.bisect(lambda M : self.get_Po_by_Postar_from_M(M) - Po_by_Postar, 1.0, 100.0)) else: return optimize.bisect(lambda M : self.get_Po_by_Postar_from_M(M) - Po_by_Postar, 1.0, 100.0) def get_P_by_Pstar_from_Po_by_Postar(self, Po_by_Postar =1.4): """Returns p/p* from po/po* equal to Po_by_Postar""" M = self.get_M_from_Po_by_Postar(Po_by_Postar) return (self.get_P_by_Pstar_from_M(M[0]),self.get_P_by_Pstar_from_M(M[1])) def get_T_by_Tstar_from_Po_by_Postar(self, Po_by_Postar): """Returns T/T* at po/po* equal to Po_by_Postar""" M = self.get_M_from_Po_by_Postar(Po_by_Postar) return (self.get_T_by_Tstar_from_M(M[0]),self.get_T_by_Tstar_from_M(M[1])) def get_To_by_Tostar_from_Po_by_Postar(self, Po_by_Postar): """Returns To/To* at po/po* equal to Po_by_Postar""" M = self.get_M_from_Po_by_Postar(Po_by_Postar) return self.get_To_by_Tostar_from_M(M) def get_rho_by_rhostar_from_Po_by_Postar(self, Po_by_Postar): """Returns rho/rho* at po/po* equal to Po_by_Postar""" M = self.get_M_from_Po_by_Postar(Po_by_Postar) return (self.get_rho_by_rhostar_from_M(M[0]),self.get_rho_by_rhostar_from_M(M[1])) def get_Qmax_by_CpT_from_Po_by_Postar(self, Po_by_Postar): """Returns Qmax/CpT at po/po* equal to Po_by_Postar""" M = self.get_M_from_Po_by_Postar(Po_by_Postar) return (self.get_Qmax_by_CpT_from_M(M[0]),self.get_Qmax_by_CpT_from_M(M[1])) def get_M_from_T_by_Tstar(self, T_by_Tstar): """Returns M at T/T* equal to T_by_Tstar""" if T_by_Tstar > self.get_T_by_Tstar_from_M(1/sqrt(self.g)): raise Exception('Value of T/T* should be less than %s' % self.get_T_by_Tstar_from_M(1/sqrt(self.g))) else: return (optimize.bisect(lambda x : self.get_T_by_Tstar_from_M(x) - T_by_Tstar, 0.001, 1.0/sqrt(self.g)),optimize.bisect(lambda x : self.get_T_by_Tstar_from_M(x) - T_by_Tstar, 1.0/sqrt(self.g), 100.0)) def get_P_by_Pstar_from_T_by_Tstar(self, T_by_Tstar): """Returns p/p* at T/T* equal to T_by_Tstar""" M = self.get_M_from_T_by_Tstar(T_by_Tstar) return (self.get_P_by_Pstar_from_M(M[0]),self.get_P_by_Pstar_from_M(M[1])) def get_Po_by_Postar_from_T_by_Tstar(self, T_by_Tstar): """Returns po/po* at T/T* equal to T_by_Tstar""" M = self.get_M_from_T_by_Tstar(T_by_Tstar) return (self.get_Po_by_Postar_from_M(M[0]),self.get_Po_by_Postar_from_M(M[1])) def get_To_by_Tostar_from_T_by_Tstar(self, T_by_Tstar): """Returns To/To* at T/T* equal to T_by_Tstar""" M = self.get_M_from_T_by_Tstar(T_by_Tstar) return (self.get_To_by_Tostar_from_M(M[0]),self.get_To_by_Tostar_from_M(M[1])) def get_rho_by_rhostar_from_T_by_Tstar(self, T_by_Tstar): """Returns rho/rho* at T/T* equal to T_by_Tstar""" M = self.get_M_from_T_by_Tstar(T_by_Tstar) return (self.get_rho_by_rhostar_from_M(M[0]),self.get_rho_by_rhostar_from_M(M[1])) def get_Qmax_by_CpT_from_T_by_Tstar(self, T_by_Tstar): """Returns Qmax/CpT at T/T* equal to T_by_Tstar""" M = self.get_M_from_T_by_Tstar(T_by_Tstar) return (self.get_Qmax_by_CpT_from_M(M[0]),self.get_Qmax_by_CpT_from_M(M[1])) def get_M_from_To_by_Tostar(self, To_by_Tostar): """Returns M at To/To* equal to To_by_Tostar""" if To_by_Tostar > 1.0: raise Exception('Value of To/To* should be less than 1') else: if To_by_Tostar > self.get_To_by_Tostar_from_M(1000.0): return (optimize.bisect(lambda x : self.get_To_by_Tostar_from_M(x) - To_by_Tostar, 0.001, 1.0),optimize.bisect(lambda x : self.get_To_by_Tostar_from_M(x) - To_by_Tostar, 1.0, 1000.0)) else: return optimize.bisect(lambda x : self.get_To_by_Tostar_from_M(x) - To_by_Tostar, 0.001, 1.0) def get_P_by_Pstar_from_To_by_Tostar(self, To_by_Tostar): """Returns p/p* at To/To* equal to To_by_Tostar""" M = self.get_M_from_To_by_Tostar(To_by_Tostar) return (self.get_P_by_Pstar_from_M(M[0]),self.get_P_by_Pstar_from_M(M[1])) def get_Po_by_Postar_from_To_by_Tostar(self, To_by_Tostar): """Returns po/po* at To/To* equal to To_by_Tostar""" M = self.get_M_from_To_by_Tostar(To_by_Tostar) return (self.get_Po_by_Postar_from_M(M[0]),self.get_Po_by_Postar_from_M(M[1])) def get_T_by_Tstar_from_To_by_Tostar(self, To_by_Tostar): """Returns T/T* at To/To* equal to To_by_Tostar""" M = self.get_M_from_To_by_Tostar(To_by_Tostar) return (self.get_T_by_Tstar_from_M(M[0]),self.get_T_by_Tstar_from_M(M[1])) def get_rho_by_rhostar_from_To_by_Tostar(self, To_by_Tostar): """Returns rho/rho* at To/To* equal to To_by_Tostar""" M = self.get_M_from_To_by_Tostar(To_by_Tostar) return (self.get_rho_by_rhostar_from_M(M[0]),self.get_rho_by_rhostar_from_M(M[1])) def get_Qmax_by_CpT_from_To_by_Tostar(self, To_by_Tostar): """Returns Qmax/CpT at To/To* equal to To_by_Tostar""" M = self.get_M_from_To_by_Tostar(To_by_Tostar) return (self.get_Qmax_by_CpT_from_M(M[0]),self.get_Qmax_by_CpT_from_M(M[1])) def get_M_from_rho_by_rhostar(self, rho_by_rhostar): """Returns Mach number M at rho/rho* equal to rho_by_rhostar""" return (1.0/((1+self.g)*rho_by_rhostar - self.g))**0.5 def get_P_by_Pstar_from_rho_by_rhostar(self, rho_by_rhostar): """Returns p/p* at rho/rho* equal to rho_by_rhostar""" M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_P_by_Pstar_from_M(M) def get_Po_by_Postar_from_rho_by_rhostar(self, rho_by_rhostar): """Returns po/po* at rho/rho* equal to rho_by_rhostar""" M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_Po_by_Postar_from_M(M) def get_T_by_Tstar_from_rho_by_rhostar(self, rho_by_rhostar): """Returns T/T* at rho/rho* equal to rho_by_rhostar""" M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_T_by_Tstar_from_M(M) def get_To_by_Tostar_from_rho_by_rhostar(self, rho_by_rhostar): """Returns To/To* at rho/rho* equal to rho_by_rhostar""" M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_To_by_Tostar_from_M(M) def get_Qmax_by_CpT_from_rho_by_rhostar(self, rho_by_rhostar): """Returns Qmax/CpT at rho/rho* equal to rho_by_rhostar""" M = self.get_M_from_rho_by_rhostar(rho_by_rhostar) return self.get_Qmax_by_CpT_from_M(M) def get_M_from_Qmax_by_CpT(self, Qmax_by_CpT): """Returns M at Qmax/CpT equal to Qmax_by_CpT""" return sqrt((Qmax_by_CpT*(self.g+1) + 1) + sqrt(((self.g+1)*Qmax_by_CpT+1)**2 - 1)) gastables/modules/setup.py0000644000175000017500000000063310765136746015276 0ustar varunvarunimport sys from distutils.core import setup setup(name='gastables', version='0.1', description="GasTables include Python modules for compressible gas flow calculations.", author="Varun Hiremath, Venkattraman A", author_email="varunhiremath@gmail.com", url="http://code.google.com/p/python-gastables/", license='GPL', platforms=['Any'], packages = ['gastables']) gastables/modules/AUTHORS0000644000175000017500000000013110732170652014611 0ustar varunvarunVarun Hiremath Venkattraman A gastables/modules/README0000644000175000017500000003434410732170652014436 0ustar varunvarunNOTATIONS: --------- M - mach number, A - area, P - pressure, T - temperature, rho - density, F - impulse function f - mean coefficient of friction D - hydraulic mean diameter Lmax - maximum pipe length required for choking conditions g = Cp/Cv (ratio of specific heats) (can be set to required value using __init__ while creating the instance of the class) SUBSCRIPTS: ---------- o - Stagnation quantity x - Upstream of shock y - Downstream of shock star - corresponding to choking condition (M = 1) starref - corresponding to M = 1/(sqrt(gamma)) Note: All the angles here are in degrees. I. Isentropic: Isentropic Flow Relations ------------------------------------------ Python module for isentropic flow properties Assumptions: 1) One dimensional isentropic flow 2) Perfect gas with constant specific heats and molecular weights Here is an example on how to use the module: In [1]: from gastables.Isentropic import Isentropic In [2]: isen = Isentropic() In [3]: isen.get_ isen.get_AP_by_AstarPo_from_M isen.get_M_from_T_by_To isen.get_AP_by_AstarPo_from_P_by_Po isen.get_M_from_rho_by_rhoo isen.get_AP_by_AstarPo_from_T_by_To isen.get_Mstar_from_M isen.get_A_by_Astar_from_M isen.get_P_by_Po_from_M isen.get_A_by_Astar_from_P_by_Po isen.get_P_by_Po_from_T_by_To isen.get_A_by_Astar_from_T_by_To isen.get_P_by_Po_from_rho_by_rhoo isen.get_A_by_Astar_from_rho_by_rhoo isen.get_T_by_To_from_M isen.get_F_by_Fstar_from_M isen.get_T_by_To_from_P_by_Po isen.get_F_by_Fstar_from_P_by_Po isen.get_T_by_To_from_rho_by_rhoo isen.get_F_by_Fstar_from_T_by_To isen.get_rho_by_rhoo_from_M isen.get_F_by_Fstar_from_rho_by_rhoo isen.get_rho_by_rhoo_from_P_by_Po isen.get_M_from_A_by_Astar isen.get_rho_by_rhoo_from_T_by_To isen.get_M_from_P_by_Po In [3]: isen.get_P_by_Po_from_M(0.5) Out[3]: 0.84301917542255311 In [4]: isen.get_P_by_Po_from_M(2.0) Out[4]: 0.12780452546295096 In [5]: isen.get_M_from_T_by_To(0.5) Out[5]: 2.2360679774997898 II. NormalShock: Normal Shock Relations ----------------------------------------- Python module for properties across a normal shock in perfect gases Assumptions: 1) One dimensional flow 2) Constant area duct 3) Perfect gas with constant specific heat and molecular weights 4) Adiabatic flow Here is an example on how to use the module: In [1]: from gastables.NormalShock import NormalShock In [2]: ns = NormalShock() In [3]: ns.get ns.get_Mx_from_My ns.get_Poy_by_Px_from_My ns.get_Mx_from_Poy_by_Pox ns.get_Poy_by_Px_from_Poy_by_Pox ns.get_Mx_from_Poy_by_Px ns.get_Poy_by_Px_from_Py_by_Px ns.get_Mx_from_Py_by_Px ns.get_Poy_by_Px_from_Ty_by_Tx ns.get_Mx_from_Ty_by_Tx ns.get_Poy_by_Px_from_rhoy_by_rhox ns.get_Mx_from_rhoy_by_rhox ns.get_Py_by_Px_from_Mx ns.get_My_from_Mx ns.get_Py_by_Px_from_My ns.get_My_from_Poy_by_Pox ns.get_Py_by_Px_from_Poy_by_Pox ns.get_My_from_Poy_by_Px ns.get_Py_by_Px_from_Poy_by_Px ns.get_My_from_Py_by_Px ns.get_Py_by_Px_from_Ty_by_Tx ns.get_My_from_Ty_by_Tx ns.get_Ty_by_Tx_from_Mx ns.get_My_from_rhoy_by_rhox ns.get_Ty_by_Tx_from_My ns.get_Poy_by_Pox_from_Mx ns.get_Ty_by_Tx_from_Poy_by_Pox ns.get_Poy_by_Pox_from_My ns.get_Ty_by_Tx_from_Poy_by_Px ns.get_Poy_by_Pox_from_Poy_by_Px ns.get_Ty_by_Tx_from_Py_by_Px ns.get_Poy_by_Pox_from_Py_by_Px ns.get_Ty_by_Tx_from_rhoy_by_rhox ns.get_Poy_by_Pox_from_Ty_by_Tx ns.get_rhoy_by_rhox_from_Mx ns.get_Poy_by_Pox_from_rhoy_by_rhox ns.get_rhoy_by_rhox_from_My ns.get_Poy_by_Px_from_Mx In [3]: ns.get_Poy_by_Po ns.get_Poy_by_Pox_from_Mx ns.get_Poy_by_Pox_from_Py_by_Px ns.get_Poy_by_Pox_from_My ns.get_Poy_by_Pox_from_Ty_by_Tx ns.get_Poy_by_Pox_from_Poy_by_Px ns.get_Poy_by_Pox_from_rhoy_by_rhox In [3]: ns.get_Poy_by_Pox_from_Mx(5) Out[3]: 0.061716319748617687 In [4]: ns.get_Poy_by_Pox_from_My(0.5) Out[4]: 0.4431116697730248 In [5]: ns.get_Ty_by_Tx_from_Po ns.get_Ty_by_Tx_from_Poy_by_Pox ns.get_Ty_by_Tx_from_Poy_by_Px In [5]: ns.get_Ty_by_Tx_from_Poy_by_Px(26.539) Out[5]: 4.87513640205 In [6]: ns.get_Mx ns.get_Mx_from_My ns.get_Mx_from_Poy_by_Px ns.get_Mx_from_Ty_by_Tx ns.get_Mx_from_Poy_by_Pox ns.get_Mx_from_Py_by_Px ns.get_Mx_from_rhoy_by_rhox In [6]: ns.get_Mx_from_Py_by_Px(25.059) Out[6]: 4.6499462362483293 III. ObliqueShock: Oblique Shock Relations. --------------------------------------------- Python module for properties behind an oblique shock in perfect gases An Oblique shock wave is inclined at an angle to the direction of upstream flow. Supersonic flow passing through an oblique shock (wave angle = beta) is deflected through an angle (delta). Assumptions: 1) Perfect gas with constant specific heats and molecular weights 2) Adiabatic flow 3) Absence of body forces 4) Absence of external work Note: By default the shcok is assumed to be a weak shock. The third argument in some functions can be passed as True for strong shock. Here is an example on how to use the module: In [2]: from gastables.ObliqueShock import ObliqueShock In [3]: os = ObliqueShock() In [4]: os.get_My_from_Mx_and_Turn_Angle(2.021,22.766) Out[4]: 1.0385397188618728 In [5]: os.get_Wave_Angle_from_Mx_and_Turn_Angle(2.021,22.766) Out[5]: 59.9807566824 # For strong shock pass True as third argument In [6]: os.get_Wave_Angle_from_Mx_and_Turn_Angle(2.021,22.766,True) Out[6]: 69.0023737176 In [7]: os.get_ os.get_My_from_Mx_and_Turn_Angle os.get_Turn_Angle_from_Mx_and_Wave_Angle os.get_Poy_by_Pox_from_Mx_and_Turn_Angle os.get_Ty_by_Tx_from_Mx_and_Turn_Angle os.get_Poy_by_Pox_from_Mx_and_Wave_Angle os.get_Ty_by_Tx_from_Mx_and_Wave_Angle os.get_Poy_by_Px_from_Mx_and_Turn_Angle os.get_Wave_Angle_from_Mx_and_Turn_Angle os.get_Poy_by_Px_from_Mx_and_Wave_Angle os.get_rhoy_by_rhox_from_Mx_and_Turn_Angle os.get_Py_by_Px_from_Mx_and_Turn_Angle os.get_rhoy_by_rhox_from_Mx_and_Wave_Angle os.get_Py_by_Px_from_Mx_and_Wave_Angle In [7]: os.get_Poy_by_Pox os.get_Poy_by_Pox_from_Mx_and_Turn_Angle os.get_Poy_by_Pox_from_Mx_and_Wave_Angle In [7]: os.get_Poy_by_Pox_from_Mx_and_Turn_Angle(3.0,30.0) Out[7]: 7.679656883341166 IV. FannoFlow: Flow of perfect gases with friction. ---------------------------------------------------- Python module for flow properties of perfect gases with friction In Fanno flow, friction in the passage leads to increase in entropy and takes the process towards the choking conditions, (M = M* = 1). Assumptions: 1) One dimensional flow with friction 2) Constant area duct 3) perfect gas with constant specific heats and molecular weights 4) adiabatic flow Here is an example on how to use the module: In [1]: from gastables.FannoFlow import FannoFlow In [2]: fanno = FannoFlow() In [3]: fanno.get fanno.get_4fLmax_by_D_from_M fanno.get_P_by_Pstar_from_M fanno.get_4fLmax_by_D_from_P_by_Pstar fanno.get_P_by_Pstar_from_T_by_Tstar fanno.get_4fLmax_by_D_from_T_by_Tstar fanno.get_P_by_Pstar_from_rho_by_rhostar fanno.get_4fLmax_by_D_from_rho_by_rhostar fanno.get_Po_by_Postar_from_M fanno.get_F_by_Fstar_from_M fanno.get_Po_by_Postar_from_P_by_Pstar fanno.get_F_by_Fstar_from_P_by_Pstar fanno.get_Po_by_Postar_from_T_by_Tstar fanno.get_F_by_Fstar_from_T_by_Tstar fanno.get_Po_by_Postar_from_rho_by_rhostar fanno.get_F_by_Fstar_from_rho_by_rhostar fanno.get_T_by_Tstar_from_M fanno.get_M_from_4fLmax_by_D fanno.get_T_by_Tstar_from_P_by_Pstar fanno.get_M_from_F_by_Fstar fanno.get_T_by_Tstar_from_rho_by_rhostar fanno.get_M_from_P_by_Pstar fanno.get_rho_by_rhostar_from_M fanno.get_M_from_Po_by_Postar fanno.get_rho_by_rhostar_from_P_by_Pstar fanno.get_M_from_T_by_Tstar fanno.get_rho_by_rhostar_from_T_by_Tstar fanno.get_M_from_rho_by_rhostar In [4]: fanno.get_4 fanno.get_4fLmax_by_D_from_M fanno.get_4fLmax_by_D_from_T_by_Tstar fanno.get_4fLmax_by_D_from_P_by_Pstar fanno.get_4fLmax_by_D_from_rho_by_rhostar In [4]: fanno.get_4fLmax_by_D_from_M(0.5) Out[4]: 1.0690603127182559 In [5]: fanno.get_F_by_Fstar_from_P_by_Pstar(2.052) Out[5]: 1.17863071465 In [6]: fanno.get_Po_by_Postar_from_M(1.2) Out[6]: 1.0304397530864196 In [7]: fanno.get_M_from_Po_by_Postar(1.005) Out[7]: (0.92428188796465904, 1.0790452746820094) In [8]: fanno.get_M_from_F_by_Fstar(1.1) Out[8]: (0.60703129627133123, 1.8436507466136263) V. Isothermal: Isothermal flow of perfect gases with friction. --------------------------------------------------------------- Python module for isothermal flow of perfect gases with friction The combined effect of friction and heat transfer in long ducts can be condidered to isothermal flow model. Here the reference value of the properties (p*, rho*,c*,To*,po* and Lmax) are taken at the Mach number M* = 1/sqrt(gamma) Assumptions: 1) One dimensional flow with friction and heat transfer 2) Constant area duct 3) Perfect gas with constant specific heat and Molecular weights 4) Isothermal flow Here is an example on how to use the module: In [1]: from gastables.Isothermal import Isothermal In [2]: isot = Isothermal() In [3]: isot.get_ isot.get_4fLmax_by_D_from_M isot.get_4fLmax_by_D_from_P_by_Pstarref isot.get_4fLmax_by_D_from_Po_by_Postarref isot.get_4fLmax_by_D_from_To_by_Tostarref isot.get_4fLmax_by_D_from_rhostarref_by_rho isot.get_M_from_4fLmax_by_D isot.get_M_from_P_by_Pstarref isot.get_M_from_Po_by_Postarref isot.get_M_from_To_by_Tostarref isot.get_M_from_rhostarref_by_rho isot.get_P_by_Pstarref_from_4fLmax_by_D isot.get_P_by_Pstarref_from_M isot.get_P_by_Pstarref_from_Po_by_Postarref isot.get_P_by_Pstarref_from_To_by_Tostarref isot.get_P_by_Pstarref_from_rhostarref_by_rho isot.get_Po_by_Postarref_from_4fLmax_by_D isot.get_Po_by_Postarref_from_M isot.get_Po_by_Postarref_from_P_by_Pstarref isot.get_Po_by_Postarref_from_To_by_Tostarref isot.get_Po_by_Postarref_from_rhostarref_by_rho isot.get_To_by_Tostarref_from_4fLmax_by_D isot.get_To_by_Tostarref_from_M isot.get_To_by_Tostarref_from_P_by_Pstarref isot.get_To_by_Tostarref_from_Po_by_Postarref isot.get_To_by_Tostarref_from_rhostarref_by_rho isot.get_rhostarref_by_rho_from_4fLmax_by_D isot.get_rhostarref_by_rho_from_M isot.get_rhostarref_by_rho_from_P_by_Pstarref isot.get_rhostarref_by_rho_from_Po_by_Postarref isot.get_rhostarref_by_rho_from_To_by_Tostarref In [3]: isot.get_P_by_Pstarref_from_M(0.5) Out[3]: 1.6903085094570331 In [4]: isot.get_M_from_P_by_Pstarref(1.69) Out[4]: 0.50009127498728789 In [5]: isot.get_Po_by_Postarref_from_M(0.72) Out[5]: 1.0389216000603498 In [6]: isot.get_Po_by_Postarref_from_4fLmax_by_D(0.0573) Out[6]: (1.0389074471204016, 1.0045176597541905) In [7]: isot.get_M_from_4fLmax_by_D(0.0573) Out[7]: (0.72002864714503501, 1.0112028829769613) V. RayleighFlow: Flow of perfect gases with friction ------------------------------------------------------- Python module for flow properties of perfect gases with heat transfer In Rayleigh flow, heat addition increases the entropy and takes the process towards the choking conditions, (M = M* = 1). This behaviour imposes a limit to heat addition, therefore for a given initial Mach number there is a fixed value of the maximum possible heat transfer (Qmax). Assumptions: 1) One dimensional flow with Heat transfer 2) Constant area duct 3) Perfect gas with constant specific heats and molecular weights Here is an example on how to use the module: In [1]: from gastables.RayleighFlow import RayleighFlow In [2]: rf = RayleighFlow() In [3]: rf.get_ rf.get_M_from_P_by_Pstar rf.get_Qmax_by_CpT_from_T_by_Tstar rf.get_M_from_Po_by_Postar rf.get_Qmax_by_CpT_from_To_by_Tostar rf.get_M_from_T_by_Tstar rf.get_Qmax_by_CpT_from_rho_by_rhostar rf.get_M_from_To_by_Tostar rf.get_T_by_Tstar_from_M rf.get_M_from_rho_by_rhostar rf.get_T_by_Tstar_from_P_by_Pstar rf.get_P_by_Pstar_from_M rf.get_T_by_Tstar_from_Po_by_Postar rf.get_P_by_Pstar_from_Po_by_Postar rf.get_T_by_Tstar_from_To_by_Tostar rf.get_P_by_Pstar_from_T_by_Tstar rf.get_T_by_Tstar_from_rho_by_rhostar rf.get_P_by_Pstar_from_To_by_Tostar rf.get_To_by_Tostar_from_M rf.get_P_by_Pstar_from_rho_by_rhostar rf.get_To_by_Tostar_from_P_by_Pstar rf.get_Po_by_Postar_from_M rf.get_To_by_Tostar_from_Po_by_Postar rf.get_Po_by_Postar_from_P_by_Pstar rf.get_To_by_Tostar_from_T_by_Tstar rf.get_Po_by_Postar_from_T_by_Tstar rf.get_To_by_Tostar_from_rho_by_rhostar rf.get_Po_by_Postar_from_To_by_Tostar rf.get_rho_by_rhostar_from_M rf.get_Po_by_Postar_from_rho_by_rhostar rf.get_rho_by_rhostar_from_P_by_Pstar rf.get_Qmax_by_CpT_from_M rf.get_rho_by_rhostar_from_Po_by_Postar rf.get_Qmax_by_CpT_from_P_by_Pstar rf.get_rho_by_rhostar_from_T_by_Tstar rf.get_Qmax_by_CpT_from_Po_by_Postar rf.get_rho_by_rhostar_from_To_by_Tostar In [3]: rf.get_P_by_Pstar_from_M(0.5) Out[3]: 1.7777777777777777 In [4]: rf.get_M_from_rho_by_rhostar(2.0) Out[4]: 0.54232614454664041 In [5]: rf.get_M_from_rho_by_rhostar(2.0) Out[5]: 0.54232614454664041 In [6]: rf.get_M_from_To_by_Tostar(0.810) Out[6]: (0.59188297137319557, 1.9193987012093878) In [7]: rf.get_Po_by_Postar_from_To_by_Tostar(0.9) Out[7]: (1.0464160348349931, 1.1402610122255414) VII: PrandtlMeyer: Prandtl Meyer functions and mach angles. ------------------------------------------------------------ Python module for Prandtl Meyer functions with Mach angles Assumptions: 1) Perfect gas with constant specific heats and molecular weights 2) Isentropic flow Here is an example on how to use the module: In [1]: from gastables.PrandtlMeyer import PrandtlMeyer In [2]: pm = PrandtlMeyer() In [3]: pm.get_ pm.get_M_from_Mach_Angle pm.get_Mach_Angle_from_M pm.get_M_from_Prandtl_Func pm.get_Prandtl_Func_from_M In [3]: pm.get_Prandtl_Func_from_M(2.0) Out[3]: 26.379760813416457 In [4]: pm.get_M_from_Prandtl_Func(_) Out[4]: 2.0 In [5]: pm.get_M_from_Prandtl_Func(30.0) Out[5]: 2.13390503323 In [6]: pm.get pm.get_M_from_Mach_Angle pm.get_Mach_Angle_from_M pm.get_M_from_Prandtl_Func pm.get_Prandtl_Func_from_M In [6]: pm.get_Mach_Angle_from_M(2.0) Out[6]: 30.000000000000004 Author: Varun Hiremath -- Varun Hiremath Sat, 24 Mar 2007 17:23:54 +0530gastables/modules/COPYING0000644000175000017500000004311010732170652014600 0ustar varunvarun GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gastables/README0000644000175000017500000000242510765136255012770 0ustar varunvarungastables: python gastable modules for compressible gas flow calculations ========================================================================= NOTATIONS: --------- M - mach number, A - area, P - pressure, T - temperature, rho - density, F - impulse function f - mean coefficient of friction D - hydraulic mean diameter Lmax - maximum pipe length required for choking conditions g = Cp/Cv (ratio of specific heats) (can be set to required value using __init__ while creating the instance of the class) SUBSCRIPTS: ---------- o - Stagnation quantity x - Upstream of shock y - Downstream of shock star - corresponding to choking condition (M = 1) starref - corresponding to M = 1/(sqrt(gamma)) Note: All the angles are in degrees. INSTALLATION: ------------ = modules = The 'modules' subfolder contains the python-modules which can be used from other python scripts. Please read the README included in the 'modules' subfolder. To install gastable modules run (as root) in the 'modules' subfolder: $ python setup.py install = gui = The 'gui' subfolder provides a graphical user interface for the gastables modules. To install the gui program, again run (as root) in the 'gui' subfolder: $ python setup.py install -- Varun Hiremath , Sun, 9 Mar 2008 23:25:40 +0530