Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Request Feature] Units managment with Pint #24

Open
GJoe2 opened this issue Aug 29, 2024 · 1 comment
Open

[Request Feature] Units managment with Pint #24

GJoe2 opened this issue Aug 29, 2024 · 1 comment

Comments

@GJoe2
Copy link

GJoe2 commented Aug 29, 2024

Hello there, I did some tests to integrate units management into Efficalc and found 'Pint' is quite good at that, here you will see an example:

from efficalc import Calculation, Comparison, Heading, Input, TextBlock, Title
from efficalc.report_builder import ReportBuilder
from pint import UnitRegistry

ureg = UnitRegistry()
Q_ = ureg.Quantity

As = 3  # Valor sin unidades
As_efficalc = Input("A_s", As, "in^2", description="Area of reinforcing steel")
As_pint = Q_(As, "inch**2")  # Valor con unidades

fy = 50
fy_efficalc = Input("f_y", fy, "ksi", description="Yield strength of reinforcing steel")
fy_pint = Q_(fy, "ksi")

fc = 4
fc_efficalc = Input("f'_c", fc, "ksi", description="Concrete compressive strength")
fc_pint = Q_(fc, "ksi")

b = 12
b_efficalc = Input("b", b, "in", description="Beam width")
b_pint = Q_(b, "inch")

B1 = 0.85
B1_efficalc = Input("\\beta_1", B1, description="Compressive stress block ratio")

a_pint = As_pint * fy_pint / (0.85 * fc_pint * b_pint)
c_pint = a_pint / B1

def calculation():
    Title("Concrete Beam Neutral Axis with Unit Handling")
    TextBlock("Determine the neutral axis depth in a singly reinforced concrete beam using Pint for unit management.")

    Heading("Inputs")
    As_efficalc  
    fy_efficalc
    fc_efficalc
    b_efficalc
    B1_efficalc

    Heading("Calculations")
    Calculation("a", As_efficalc * fy_efficalc / (0.85 * fc_efficalc * b_efficalc), str(a_pint.units), result_check=True)
    Calculation(
        "c",
        a_pint.magnitude / B1_efficalc,  
        str(c_pint.units),
        result_check=True,
        description="Neutral axis depth",
        reference="ACI 318-14 22.2.2.4.1",
    )

    Comparison(c_pint.magnitude, ">", 3.5, result_check=True)

builder = ReportBuilder(calculation)
builder.view_report()

This workaround calculates 2 times, one for Efficalc and another for pint. It would be desirable only one calculation, to do so I see two options:

a) Baked Pint into Efficalc so It reuses the same variable for both cases or at least can understand what Pint output is giving
b) Make a translation layer that integrates Pint with Efficalc

What are your thoughts in this matter?

@youandvern
Copy link
Owner

Hey, thanks for bringing this up and testing it! I'm not sure why it would double calculate with the library, so I'll have to spend some time exploring the code.

For a solution, I'm open to any option that:

  1. Lets users run calcs with or without Pint units, and
  2. Handles pint units in the background without any change to the call sites. The use with pint units should be identical to using efficalc without pints from the user perspective (except one includes the pint unit and the other does not)

If find a solution then feel free to draft a PR to update the library. But if not, I'll spend some time on this in the coming weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants