efficalc icon indicating copy to clipboard operation
efficalc copied to clipboard

[Request Feature] Units managment with Pint

Open GJoe2 opened this issue 5 months ago • 1 comments

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?

GJoe2 avatar Aug 29 '24 05:08 GJoe2