def max_stress_calculator(row_dict, temp): temp_list = [ 100, 150, 200, 250, 300, 400, 500, 600, 650, 700, 750, 800, 850, 900, 950, 1000 ] # temp = data1.get('temp1') max_stress = 0 for temperature_index in range(len(temp_list)): if temp <= temp_list[0]: max_stress = row_dict['max_stress_20_100'] return max_stress elif temp > temp_list[len(temp_list) - 1]: raise newError( {"temp_error": ["Temperatue is too high for the material"]}) elif temp_list[temperature_index] == temp: max_stress = row_dict['max_stress_' + str(temp)] return max_stress elif temp_list[temperature_index] > temp: max_stress1 = 0 if temp_list[temperature_index - 1] == temp_list[0]: max_stress1 = row_dict['max_stress_20_100'] else: max_stress1 = row_dict['max_stress_' + str(temp_list[temperature_index - 1])] max_stress2 = row_dict['max_stress_' + str(temp_list[temperature_index])] temperature1 = temp_list[temperature_index - 1] temperature2 = temp_list[temperature_index] max_stress = (((max_stress2 - max_stress1) * (temp - temperature1)) / (temperature2 - temperature1)) + max_stress1 return max_stress
def post(self, request, format=None): data = request.data.get('conicalParam', {}) data['projectID'] = request.data.get('projectID', None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict = MaximumAllowableStress.objects.filter( spec_num=data1.get('spec_num')).filter( type_grade=data1.get('type_grade')).values()[0] except: raise newError( {"database": ["Data cannot be found incorrect data"]}) temp = data1.get('temp1') max_stress = row_dict['max_stress_' + str(temp)] P = data1.get('ip') S = max_stress D_l = data1.get('sd_l') D_s = data1.get('sd_s') L_c = data1.get('length') C_A = data1.get('ic') projectID = data1.get('projectID') thickness = conical_t(P, S, D_l, D_s, L_c, C_A, projectID) newdict = {'thickness': thickness} newdict.update(serializer.data) return Response(newdict, status=status.HTTP_200_OK)
def post(self, request, format=None): data = request.data.get('cylinderParam', {}) data['projectID'] = request.data.get('projectID', None) # data['componentID'] = request.data.get('componentID',None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict = MaximumAllowableStress.objects.filter( spec_num=data1.get('spec_num')).filter( type_grade=data1.get('type_grade')).values()[0] except: raise newError( {"database": ["Data cannot be found incorrect data"]}) temp = data1.get('temp1') max_stress = row_dict['max_stress_' + str(temp)] P = data1.get('ip') S = max_stress D = data1.get('sd') C_A = data1.get('ic') density = row_dict['density'] projectID = data1.get('projectID') component_react_id = data1.get('componentID') thickness = cylinder_t(P, S, D, C_A, projectID, component_react_id) weightOfCylinder = center_of_gravity(D, 48, density, 60, thickness - C_A) newdict = { 'thickness': thickness, 'weight': weightOfCylinder[1], 'weightTimesCG': weightOfCylinder[0] } newdict.update(serializer.data) return Response(newdict, status=status.HTTP_200_OK)
def post(self, request, format=None): data = request.data.get('skirtParam', {}) data['projectID'] = request.data.get('projectID',None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict = MaximumAllowableStress.objects.filter(spec_num=data1.get('spec_num')).filter(type_grade=data1.get('type_grade')).values()[0] except: raise newError({ "database":["Data cannot be found incorrect data"] }) max_stress = max_stress_calculator(row_dict, data1.get('temp1')) yield_strength = row_dict['min_yield_strength'] # modulus of elasticity at design temp S = max_stress D = data1.get('sd') C_A = data1.get('ic') thickness = data1.get('thickness') length = data1.get('length') density = row_dict['density'] projectID = data1.get('projectID') component_react_id = data1.get('componentID') thicknessResponse = skirtCalculation(D, thickness, C_A, S*1000, projectID, component_react_id) weightResponse = center_of_gravity(D,length+4,density,thickness-C_A) newdict = { 'thicknessResponse':thicknessResponse, 'weight':weightResponse } newdict.update(serializer.data) return Response(newdict,status=status.HTTP_200_OK)
def post(self, request, format=None): data = request.data.get('skirtParam', {}) data['projectID'] = request.data.get('projectID', None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict = MaximumAllowableStress.objects.filter( spec_num=data1.get('spec_num')).filter( type_grade=data1.get('type_grade')).values()[0] except: raise newError( {"database": ["Data cannot be found incorrect data"]}) temp = data1.get('temp1') max_stress = row_dict['max_stress_' + str(temp)] yield_strength = row_dict['min_yield_strength'] # modulus of elasticity at design temp S = max_stress D = data1.get('sd') C_A = data1.get('ic') thickness = data1.get('thickness') print(D, thickness, C_A, S) projectID = data1.get('projectID') thicknessResponse = skirtCalculation(D, thickness, C_A, S * 1000, projectID) newdict = {'thicknessResponse': thicknessResponse} newdict.update(serializer.data) return Response(newdict, status=status.HTTP_200_OK)
def post(self, request): data = request.data.get('nozzleParam', {}) data['projectID'] = request.data.get('projectID', None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict_nozzle = NozzleData.objects.filter( class_value=data1.get('class_value') ).filter(type_name=data1.get('type_name')).filter( nominal_pipe_size=data1.get('nominal_pipe_size')).values()[0] row_dict_stress = MaximumAllowableStress.objects.filter( spec_num=data1.get('spec_num')).filter( type_grade=data1.get('type_grade')).values()[0] # row_dict_pipe = PipingSchedule.objects.filter(schedules=data1.get('schedules')).filter(nominal_pipe_size=data1.get('nominal_pipe_size')).values()[0] except: raise newError( {"database": ["Data cannot be found incorrect data"]}) designPressure = data1.get('designPressure') corrosionAllowance = data1.get('corrosionAllowance') temp = data1.get('temp1') shellAllowableStress = row_dict_stress['max_stress_' + str(temp)] yieldStrength = row_dict_stress['min_yield_strength'] cylinderInsideDiameter = data1.get('cylinderDiameter') cylinderThickness = data1.get('cylinderThickness') # nozzleOutsideDiameter = data1.get('nozzleDiameter') nozzleThickness = row_dict_nozzle['neck_thickness'] externalNozzleProjection = data1.get('externalNozzleProjection') internalNozzleProjection = data1.get('internalNozzleProjection') # print(yieldStrength,nozzleThickness,shellAllowableStress) nozzleOutsideDiameter = row_dict_nozzle['flange_outer_diameter'] # nozzleThickness = 4.75 nozzleAllowableStress = shellAllowableStress * 1000 reinforcingElementAllowableStress = shellAllowableStress * 1000 projectID = data1.get('projectID') component_react_id = data1.get('componentID') value = calculation_thick( designPressure, corrosionAllowance, shellAllowableStress * 1000, yieldStrength * 1000, cylinderInsideDiameter, cylinderThickness, nozzleOutsideDiameter, nozzleThickness, externalNozzleProjection, internalNozzleProjection, nozzleAllowableStress, reinforcingElementAllowableStress, projectID, component_react_id) newdict = { "areaAvailable": value[0], "areaRequired": value[1], "areaResponse": value[2] } newdict.update(serializer.data) newdict.update(row_dict_nozzle) # newdict.update(row_dict_pipe) return Response(newdict, status=status.HTTP_200_OK)
def post(self, request, format=None): data = request.data.get('saddleParam',{}) data['projectID'] = request.data.get('projectID',None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict = MaximumAllowableStress.objects.filter(spec_num=data1.get('vessel_spec_num')).filter(type_grade=data1.get('vessel_type_grade')).values()[0] except: raise newError({ "database":["Data cannot be found incorrect data"] }) max_stress = max_stress_calculator(row_dict, data1.get('vessel_design_temperature')) vessel_yield_stress = row_dict['min_yield_strength'] vessel_diameter = data1.get('vessel_diameter') vessel_thickness = data1.get('vessel_thickness') vessel_corrosion_allowance = data1.get('vessel_corrosion_allowance') vessel_head_height = data1.get('vessel_head_height') vessel_design_pressure = data1.get('vessel_design_pressure') weld_joint_effiency = data1.get('weld_joint_effiency') # need to be take from user length_of_vessel = data1.get('length_of_vessel') saddle_center_line_to_head = data1.get('saddle_center_line_to_head') saddle_contact_angle = data1.get('saddle_contact_angle') saddle_width = data1.get('saddle_width') total_vessel_weight = data1.get('total_vessel_weight') projectID = data1.get('projectID') component_react_id = data1.get('componentID') responses = saddleCalc( vessel_diameter=vessel_diameter, vessel_thickness=vessel_thickness, vessel_corrosion_allowance=vessel_corrosion_allowance, vessel_head_height=vessel_head_height, vessel_design_pressure=vessel_design_pressure, vessel_allowable_pressure=max_stress*1000, vessel_yield_stress=vessel_yield_stress*1000, weld_joint_effiency=weld_joint_effiency, length_of_vessel=length_of_vessel, saddle_center_line_to_head=saddle_center_line_to_head, saddle_contact_angle=saddle_contact_angle, saddle_width=saddle_width, total_vessel_weight=total_vessel_weight, report_id=projectID, component_react_id=component_react_id ) newdict = {"responses":responses} newdict.update(serializer.data) return Response(newdict,status=status.HTTP_200_OK)
def post(self, request, format=None): data = request.data.get('headParam', {}) data['projectID'] = request.data.get('projectID', None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data try: row_dict = MaximumAllowableStress.objects.filter( spec_num=data1.get('spec_num')).filter( type_grade=data1.get('type_grade')).values()[0] except: raise newError( {"database": ["Data cannot be found incorrect data"]}) max_stress = max_stress_calculator(row_dict, data1.get('temp1')) hrAll = data1.get('hr').split(":") hrUpperPart = int(hrAll[0]) hrLowerPart = int(hrAll[1]) P = float(data1.get('ip')) S = max_stress D = float(data1.get('sd')) C_A = float(data1.get('ic')) density = row_dict['density'] projectID = data1.get('projectID') component_react_id = data1.get('componentID') srl = data1.get('srl') position = "" if data1.get('position') == 1: position = "top" else: position = "bottom" thickness = head_t(P, S, D, C_A, position, projectID, component_react_id) weightData = center_of_gravity(D, density, thickness[0] - C_A, srl) newdict = { 'thickness': thickness[0], 'MAWP': thickness[1], 'MAWPResponse': thickness[2], 'weight': weightData } newdict.update(serializer.data) return Response(newdict, status=status.HTTP_200_OK)
def skirtCalculation(diameter, thickness, corossionAllowance, stress, report_id, component_react_id): diameterInside = diameter + 2 * corossionAllowance radiusInside = 0.5 * diameterInside thicknessCorroded = thickness - corossionAllowance diameterOutside = diameter + 2 * thicknessCorroded radiusOutside = 0.5 * diameterOutside # variable for defining steps response_skirt = "" next_step = True ''' In accordance with VIII-2, paragraph 4.3.10.2, the following procedure shall be used to design cylindrical, spherical, and conical shells subjected to internal pressure plus supplemental loads of applied net section axial force, bending moment, and torsional moment. By inspection of the results shown in Table E4.15.2.2 and Table E4.15.2.3, Load Case 6 is determined to be a potential governing load case. The pressure, net section axial force, and bending moment at the location of interest for Load Case 6 are: So P = Ps = 0.0 psi F6 = -427775 lbs M6 = 21900435 in - lbs ''' # TODO: given need to know what it is P = 0.0 F6 = -437775 M6 = 21900435 ''' STEP 1 – Calculate the membrane stress for the cylindrical shell. Note that the circumferential membrane stress, sigmaThetam , is determined based on the equations in UG-27(c)(1) and the exact strength of materials solution for the longitudinal membrane stress, sigmasm , is used in place of the approximate solution provided in UG-27(c)(2). The shear stress is computed based on the known strength of materials solution. For the skirt, weld joint efficiency is set as E = 1.0 . Note: theta is defined as the angle measured around the circumference from the direction of the applied bending moment to the point under consideration. For this example problem theta = 0.0 deg to maximize the bending stress ''' # TODO: given need to know what it is theta = 0.0 E = 1.0 sigmaThetam = (((P * radiusInside) / thicknessCorroded) + 0.6 * P) / E sigmasmSection1 = (P * m.pow(diameterInside, 2)) / ( m.pow(diameterOutside, 2) - m.pow(diameterInside, 2)) sigmasmSection2 = (4 * F6) / ( m.pi * (m.pow(diameterOutside, 2) - m.pow(diameterInside, 2))) sigmasmSection3 = (32 * M6 * diameterOutside * m.cos(theta)) / ( m.pi * (m.pow(diameterOutside, 4) - m.pow(diameterInside, 4))) sigmasmadd = (sigmasmSection1 + sigmasmSection2 + sigmasmSection3) / E sigmasmsub = (sigmasmSection1 + sigmasmSection2 - sigmasmSection3) / E # TODO: given need to know what it is Mt = 0.0 tilde = (16 * Mt * diameterOutside) / ( m.pi * (m.pow(diameterOutside, 4) - m.pow(diameterInside, 4))) ''' STEP 2 – Calculate the principal stresses ''' sigma1 = 0.5 * ( sigmaThetam + sigmasmsub + m.sqrt(m.pow((sigmaThetam - sigmasmsub), 2) + 4 * m.pow(tilde, 2))) sigma2 = 0.5 * ( sigmaThetam + sigmasmsub - m.sqrt(m.pow((sigmaThetam - sigmasmsub), 2) + 4 * m.pow(tilde, 2))) sigma3 = -0.5 * P ''' STEP 3 – Check the allowable stress acceptance criteria. ''' sigmae = (1 / m.sqrt(2)) * m.sqrt( m.pow((sigma1 - sigma2), 2) + m.pow((sigma2 - sigma3), 2) + m.pow((sigma3 - sigma1), 2)) if (sigmae <= stress) and next_step: pass else: next_step = False response_skirt = 'need to change the parameters' # return 'need to change the parameters' ''' STEP 4 – For cylindrical and conical shells, if the meridional stress, sigmasm is compressive, then check the allowable compressive stress per UG-23(b).Sincesigmasm is compressive, {sigmasm = -3421.0021 psi < 0 } , a compressive stress check is required. sigmasm <= Fxa (Fxa =0) ''' # TODO: need to be verified Fxa = 0.0 if (sigmasmsub < Fxa) and next_step: pass else: next_step = False response_skirt = 'not compressive' # return 'not compressive' ''' Evaluate per paragraph UG-23(b). The maximum allowable longitudinal compressive stress to be used in the design of cylindrical shells or tubes, either seamless or butt welded, subjected to loadings that produce longitudinal compression in the shell or tube shall be the smaller of the maximum allowable tensile stress value shown in STEP 3 or the value of the factor B determined by the following procedure where the joint efficiency for butt welded joints shall be taken as unity. ''' # weldJointEffiency = 1.0 # as above paragraph ''' STEP 4.1 – Using the selected values of thicknessCorroded and radiusOutside , calculate the value of factor A using the following formula ''' factorA = (0.125 * thicknessCorroded) / radiusOutside ''' STEP 4.2 – Using the value of A calculated in STEP 4.1, enter the applicable material chart in Subpart 3 of Section II, Part D for the material under consideration. Move vertically to an intersection with the material/temperature line for the design temperature. Interpolation may be made between lines for intermediate temperatures. In cases where the value of A falls to the right of the material/temperature line, assume and intersection with the horizontal projection of the upper end of the material/temperature line. For values of A falling to the left of the material/temperature line, see STEP 4.4. Per Section II Part D, Table 1A, a material specification of SA-516-70 N is assigned an External Pressure Chart No. CS-2. STEP 4.3 – From the intersection obtained in Step 4.2, move horizontally to the right and read the value of factor B . This is the maximum allowable compressive stress for the values of t and R o used in STEP 4.1. ''' factorB = 12300 #psi ''' STEP 4.4 – For values of A falling to the left of the applicable material/temperature line, the value of B shall be calculated using the following formula: factorB = (factorA * E) / 2 Not required ''' ''' STEP 4.5 – Compare the calculated value of factorB obtained in STEPS 4.3 or 4.4 with the computed longitudinal compressive stress in the cylindrical shell or tube, using the selected values of thicknessCorroded and radiusOutside . If the value of factorB is smaller than the computed compressive stress, a greater value of thicknessCorroded must be selected and the design procedure repeated until a value of factorB is obtained that is greater than the compressive stress computed for the loading on the cylindrical shell or tube. ''' if (abs(sigmasmsub) <= factorB) and next_step: response_skirt = 'The allowable compressive stress criterion is satisfied.' # return 'The allowable compressive stress criterion is satisfied.' else: response_skirt = 'The allowable compressive stress criterion is not satisfied.' # return 'The allowable compressive stress criterion is not satisfied.' try: report = Report.objects.get(id=report_id) except: raise newError( {"database": ["Report cannot be found Please Create the report"]}) try: component = Component.objects.filter( report__id=report_id, react_component_id=component_react_id)[0] except: raise newError({ "database": ["Component cannot be found Please Create the component"] }) skirt_state = SkirtState.objects.filter( report__id=report_id, component__id=component.id).update( response_skirt=response_skirt, thickness=thickness, corrosion_allowance=corossionAllowance) if not skirt_state: calc_steps = SkirtState( report=Report.objects.get(id=report_id), component=component, # provide the component object here response_skirt=response_skirt, thickness=thickness, corrosion_allowance=corossionAllowance) calc_steps.save() return response_skirt
def calculation_thick(designPressure, corrosionAllowance, shellAllowableStress, yieldStrength, cylinderInsideDiameter, cylinderThickness, nozzleOutsideDiameter, nozzleThickness, externalNozzleProjection, internalNozzleProjection, nozzleAllowableStress, reinforcingElementAllowableStress, report_id, component_react_id, weldJointEfficiency=1.0): # Available datas # Design Conditions = 356 psig@ 300 degree F # Corrosion Allowance = 0.125 in # Weld Joint Efficiency = 1.0 # Shell Material = SA-516-70N, 2007 # Shell Allowable Stress = 20000 psi # Yield Strength = 33600 psi # Nozzle Material = SA-105, 2007 # Nozzle Allowable Stress = 20000 psi # Cylinder Inside Diameter = 150.0 in # Cylinder Thickness = 1.8125 in # Nozzle Outside Diameter = 25.5 in # Nozzle Thickness = 4.75 in # External Nozzle Projection = 14.1875 in # Internal Nozzle Projection = 0.0 in # The nozzle is inserted thorough the shell, i.e set-in type nozzle # variable meanings - # CDi = 150.0 # inch CDi = cylinderInsideDiameter # CDi = Cylinder inside Diameter. # C_A = 0.125 C_A = corrosionAllowance # C_A = corrosion Allowance # CRi = Cylinder inside Radius # Ct = 1.8125 Ct = cylinderThickness # Ct = Cylinder Thickness # Nt = 4.75 Nt = nozzleThickness # Nt = Nozzle Thickness # Nr = Nozzle Radius # ND = 25.5 ND = nozzleOutsideDiameter # ND = Nozzle Diameter # Nd = --- # Ctr = Cylinder Required Thickness # DP = 351 DP = designPressure # DP = Design Pressure # SAS = 20000 SAS = shellAllowableStress # SAS = Shell Allowable Stress # WJE = 1.0 WJE = weldJointEfficiency # WJE = Weild Joint Efficiency # Ntr = Nozzle Required Thickness # Sn = 20000 Sn = nozzleAllowableStress # Sn = Nozzle Allowable Stress # Sv = 20000 Sv = shellAllowableStress # Sv = Shell Allowable Stress # Sp = 20000 Sp = reinforcingElementAllowableStress # Sp = Reinforcing Element Allowable Stress # Establish the corroded dimensions CDi = CDi + 2 * (C_A) # Di CRi = (CDi / 2.0) # R Ct = Ct - C_A # t Nt = Nt - C_A # tn Nr = (ND - 2 * (Nt)) / 2.0 # Rn Nd = 2 * Nr # d # Calculation as per Section VIII, Division I Solution # Evaluate per UG-37 # The required thickness of the shell based on circumferential stress is give by UG-27 (c)(1). Ctr = float((DP * CRi) / ((SAS * WJE) - (0.6 * DP))) # tr # The required thickness of the nozzle based on circumferential stress is given by UG-27(c)(1). Ntr = float((DP * Nr) / ((SAS * WJE) - (0.6 * DP))) # trn # STEP 1: - Calculate the Limits of Reinforcement per UG-40 # 1) Reinforcing dimensions for an integrally reinforced nozzle per Fig. UG-40(e), UG-40(e-1), UG-40(e-2) # tx = thickness of Pipe used (assumed using figure4.5.1) tx = 4.75 # L = Length of pipe projecting outside (assumed using figure4.5.1) ''' From UG-37 Nomenclature (pg 40) (102) L = length of projection defining the thickened portion of integral reinforcement of a nozzle neck beyond the outside surface of the vessel wall [see Figure UG-40 sketch (e)] ''' L = 7.1875 ''' From UG-37 Nomenclature (pg 40) (102) tn = nozzle wall thickness. 29 Except for pipe, this is the wall thickness not including forming allowances. For pipe, use the nominal thickness [see UG-16(d)] ''' tn = 0 ''' From UG-37 Nomenclature (pg 40) (102) te = thickness or height of reinforcing element (see Figure UG-40) ''' te = 0 # From UG-37 Nomenclature (pg 40) (102) # Dp = outside diameter of reinforcing element # actual size of reinforcing element may exceed the limits of reinforcement established by UG-40; # however, credit cannot be taken for any material outside these limits Dp = 0 # check condition if (L < 2.5 * tx): # use UG-40(e-1) # Net = Neck Thickness Net = 9.5 # NIr = Nozzle Inside Radius NIr = 8.0 # Theta = Angle Theta = 30 tn = Net - NIr - C_A te = (tx - (Net - NIr)) / m.tan(Theta) Dp = ND # with reinforcing element A5 area else: # use UG-40(e-2) tn = Net - NIr - C_A te = 0 Dp = ND # without reinforcing element no A5 area # 2) The limits of reinforcement, measured parallel to the vessel wall in the corroded condition: maxValue = max(Nd, (Nr + Nt + Ct)) # 3) The limits of reinforcement, measured normal to the vessel wall in the corroded condition: minValue = min(2.5 * Ct, 2.5 * Nt + te) # STEP 2 - Calculate reinforcement strength parameters per UG-37 # 1) Strength Reduction Factors: ''' From UG-37 Nomenclature (pg 40) (102) fr = strength reduction factor, not greater than 1.0 [see UG-41(a)] fr1 = Sn/Sv for nozzle wall inserted through the vessel wall fr1 = 1.0 for nozzle wall abutting the vessel wall and for nozzles shown in Figure UG-40,sketch (j), (k), (n) and (o). fr2 = Sn/Sv fr3 = (lesser of Sn or Sp )/Sv fr4 = Sp/Sv ''' ''' From UG-37 Nomenclature (pg 40) (102) S = allowable stress value in tension (see UG-23),psi (MPa) Sn = allowable stress in nozzle, psi (MPa) (see S above) Sp = allowable stress in reinforcing element (plate), psi (MPa) (see S above) Sv = allowable stress in vessel, psi (MPa) (see S above) ''' fr1 = Sn / Sv fr2 = Sn / Sv fr3 = min(Sn, Sp) / Sv fr4 = Sp / Sv # 2) Joint Efficiency Parameter: For a nozzle located in a solid plate ''' From UG-37 Nomenclature (pg 40) (102) E 1 = 1 when an opening is in the solid plate or in a Category B butt joint = 0.85 when an opening is located in an ERW or autogenously welded pipe or tube. If the ERW or autogenously welded joint is clearly identifiable and it can be shown that the opening does not pass through this weld joint, then E1 may be determined using the other rules of this paragraph = joint efficiency obtained from Table UW-12 when any part of the opening passes through any other welded joint ''' E1 = 1.0 # 3) Correction Factor for variation of internal pressure stresses on different planes with respect to the axis of the vessel: # For a radial nozzle in a cylinder shell ''' From UG-37 Nomenclature (pg 40) (102) F = correction factor that compensates for the variation in internal pressure stresses on different planes with respect to the axis of a vessel. A value of 1.00 shall be used for all configurations except that Figure UG-37 may be used for integrally reinforced openings in cylindrical shells and cones. [See UW-16(c)(1).] ''' F = 1.0 # STEP 3 - Calculate the Areas of Reinforcement, see Fig. UG-37.1 (With Reinforcing Element, per Fig. UG-40(e-1)). # 1) Area Required, A # From UG-37 Nomenclature (pg 39) (101) # A = total cross-sectional area of reinforcement required in the plane under consideration (see Figure UG-37.1) # includes consideration of nozzle area through shell if Sn/Sv < 1.0 A = Nd * Ctr * F + 2 * Nt * Ctr * F * (1 - fr1) # 2) Area Available in the Shell, A1. Use larger value A11 = Nd * ((E1 * Ct) - (F * Ctr)) - 2 * Nt * \ ((E1 * Ct) - (F * Ctr)) * (1 - fr1) A12 = 2 * (Ct - Nt) * ((E1 * Ct) - (F * Ctr)) - 2 * \ Nt * ((E1 * Ct) - (F * Ctr)) * (1 - fr1) # From UG-37 Nomenclature (pg 39) (101) # A1 = area in excess thickness in the vessel wall available for reinforcement (see Figure UG-37.1) # includes consideration of nozzle area through shell if Sn/Sv < 1.0 A1 = max(A11, A12) # 3) Area Available in the Nozzle projecting Outward A2, Use Smaller value A21 = 5 * (Nt - Ntr) * fr2 * Ct A22 = 2 * (Nt - Ntr) * ((2.5 * Nt) + te) * fr2 # From UG-37 Nomenclature (pg 39) (101) # A2 = area in excess thickness in the nozzle wall available for reinforcement (see Figure UG-37.1) A2 = min(A21, A22) # 4) Area Available in the Nozzle Projecting Inward, A3. Use smaller value. ''' From UG-37 Nomenclature (pg 40) (102) ti = nominal thickness of internal projection of nozzle wall ti = Internal Nozzle Projection (Given by user or from database) ''' ti = 0 ''' From UG-37 Nomenclature (pg 40) (102) h = distance nozzle projects beyond the inner surface of the vessel wall. (Extension of the nozzle beyond the inside surface of the vessel wall is not limited; however, for reinforcement calculations, credit shall not be taken for material outside the limits of reinforcement established by UG-40.) h = Internal projected Nozzle height (Given by user) ''' h = 0 # ??? Cm1 = 5 * Ct * ti * fr2 Cm2 = 5 * ti * ti * fr2 Cm3 = 2 * h * ti * fr2 # From UG-37 Nomenclature (pg 40) (102) # A3 = area available for reinforcement when the nozzle extends inside the vessel wall (see Figure UG-37.1) A3 = min(Cm1, Cm2, Cm3) # 5) Area Available in Welds, A41,A42,A43, Use the following minimum specified weld leg dimensions, see Figure E4.5.1 of the example: # Outer Nozzle Fillet Weld leg : 0.375 in Onfwl = 0.375 # leg # Outer Element Fillet Weld leg : 0.0 in Oefwl = 0.0 # Inner Element Fillet Weld leg : 0.0 in Iefwl = 0.0 # From UG-37 Nomenclature (pg 40) (102) # A41,A42,A43 = cross‐sectional area of various welds available for reinforcement (see Figure UG-37.1) A41 = m.pow(Onfwl, 2) * fr3 if te: A42 = m.pow(Oefwl, 2) * fr4 # might be in example 0.0 given # else: A42 = 0 A43 = m.pow(Iefwl, 2) * fr2 # might be in example 0.0 given # 6) Area Available in Element, A5: # From UG-37 Nomenclature (pg 40) (102) # A5 = cross‐sectional area of material added as reinforcement (see Figure UG-37.1) A5 = (Dp - Nd - (2 * Nt)) * te * fr4 # Note: The thickness of the reinforcing pad, te , exceed the outer vertical reinforcement zone limit. Therefore, the reinforcement area in the pad is limited to within the zone. # 7) Total Available Area, Aavail : Aavail = A1 + A2 + A3 + (A41 + A42 + A43) + A5 # STEP 4 - Nozzle reinforcement acceptance criterion: msg = 'none' if Aavail > A: # Therefore, the nozzle is adequately reinforced msg = 'Therefore, the nozzle is adequately reinforced' else: # need to be done something msg = 'Area needs to be increased' # save the calculation steps in the state # check if the cylinder is a new one or older try: report = Report.objects.get(id=report_id) except: raise newError( {"database": ["Report cannot be found Please Create the report"]}) try: component = Component.objects.filter( report__id=report_id, react_component_id=component_react_id)[0] except: raise newError({ "database": ["Component cannot be found Please Create the component"] }) nozzle_state = NozzleState.objects.filter( report__id=report_id, component__id=component.id).update(L_R=maxValue, d=Nd, R_n=Nr, C_n=C_A, t_n=nozzleThickness, t=cylinderThickness, L_H=minValue, t_e=te, t_rn=Ntr, P=DP, S_n=SAS, E=WJE, t_r=Ctr, R_o=CRi, msg=msg) if not nozzle_state: calc_steps = NozzleState( report=Report.objects.get(id=report_id), component=component, # provide the component object here L_R=maxValue, d=Nd, R_n=Nr, C_n=C_A, t_n=nozzleThickness, t=cylinderThickness, L_H=minValue, t_e=te, t_rn=Ntr, P=DP, S_n=SAS, E=WJE, t_r=Ctr, R_o=CRi, msg=msg) calc_steps.save() return (Aavail, A, msg)
def head_t(P, S, diameterWithOutCorrosion, corrosionAllowance, position, report_id, component_react_id, E=1.0): """Calculate thickness as per ASME DIV I Parameters ---------- P : float Design Pressure or max. allowable working pressure psi. S : int Stress value of material psi. D : inch float Inside diameter . CA : float Corrosion Allowance. E : float max 1 Joint efficiency. Returns ------- float thickness. """ upper_part = float(P * diameterWithOutCorrosion) lower_part = float( (2 * S * 1000 * E) - (0.2 * P) ) thicknessWithCorrosion = (upper_part/lower_part) + corrosionAllowance thicknessWithCorrosion = 1.125 heightWithOutCorrosion = diameterWithOutCorrosion/4 ''' From ASME Section VIII Div 1 Rules for Construction.pdf An acceptable approximation of a 2:1 ellipsoidal head is one with a knuckle radius of 0.17D and a spherical radius of 0.90D . ''' sphericalRadius = 0.90 * diameterWithOutCorrosion knuckleRadius = 0.17 * diameterWithOutCorrosion ''' From pdf Examples Problem Manual VIII-1.pdf page 39 Example E4.3.5 - Elliptical Head Determine the elliptical head diameter to height ratio, k , and adjust for corrosion allowance. ''' kFactor = diameterWithOutCorrosion/(2*heightWithOutCorrosion) diameterWithCorrosion = diameterWithOutCorrosion + 2*corrosionAllowance sphericalRadiusWithCorrosion = sphericalRadius + corrosionAllowance knuckleRadiusWithCorrosion = knuckleRadius + corrosionAllowance thicknessWithOutCorrosion = thicknessWithCorrosion - corrosionAllowance ''' Section VIII, Division 1 Solution Evaluate per Mandatory Appendix 1-4(c). Note, the rules of UG-32(d) can also be used to evaluate ellipsoidal heads. However, the rules contained in this paragraph are only applicable for a specific geometry, i.e. half the minor axis (inside depth of head minus the skirt) equals one–fourth of the inside diameter of the head skirt. Additionally, if the ratio ts / L >= 0.002 , is not satisfied, the rules of Mandatory Appendix 1-4(f) shall also be met. ''' KFactor = (1/6.0)*( 2 + pow(kFactor,2)) MAWPressure = (2 * S *1000 * E * thicknessWithOutCorrosion) / ((KFactor*diameterWithCorrosion) + (0.2 * thicknessWithOutCorrosion)) comparisionFactor = thicknessWithOutCorrosion/sphericalRadiusWithCorrosion msg = "" if comparisionFactor >= 0.002: msg = "the rules of 1- 4(f) are not required" else : msg = "the rules of Mandatory Appendix 1-4(f) shall also be met" try: report = Report.objects.get(id=report_id) except: raise newError({ "database":["Report cannot be found Please Create the report"] }) try: component = Component.objects.filter( report__id=report_id, react_component_id=component_react_id)[0] except: raise newError({ "database":["Component cannot be found Please Create the component"] }) head_state = HeadState.objects.filter( report__id=report_id, component__id=component.id).update( position = position, P = P, D_o = diameterWithOutCorrosion, K = KFactor, S = S, E = E, C_A = corrosionAllowance, t = thicknessWithCorrosion ) if not head_state: calc_steps = HeadState( report=Report.objects.get(id=report_id), component=component, # provide the component object here position = position, P = P, D_o = diameterWithOutCorrosion, K = KFactor, S = S, E = E, C_A = corrosionAllowance, t = thicknessWithCorrosion ) calc_steps.save() return thicknessWithCorrosion, MAWPressure, msg
def cylinder_t(P, S, D, C_A, report_id, component_react_id, E=1.0): """Calculate thickness as per ASME DIV I Parameters ---------- P : float psi Design pressure or max allowable working pressure. S : float psi Stress value of material. D : float inches Inside diameter. CA : float inches Corrosion allowance. E : float max 1.0 Joint Efficiency. Returns ------- float Description of returned object. """ # Process to calculate using Postgres Procedure # with connection.cursor() as cursor: # cursor.callproc('cylinder_t', [P, S, D, C_A, E]) # return cursor.fetchall()[0][0] R = float((D+2*C_A)/2) upper_part = float(P * R) lower_part = float((S * 1000 * E) - (0.6 * P)) t_inter = upper_part/lower_part t = t_inter + C_A # think about how you can save the calculation steps later # check if the cylinder is a new one or older try: report = Report.objects.get(id=report_id) except: raise newError({ "database":["Report cannot be found Please Create the report"] }) try: component = Component.objects.filter( report__id=report_id, react_component_id=component_react_id)[0] except: raise newError({ "database":["Component cannot be found Please Create the component"] }) cylinder_state = CylinderState.objects.filter( report__id=report_id, component__id=component.id).update( P=P, D=D, C_A=C_A, R=D/2.0, S=S, E=E, t_inter=t_inter, t=t ) if not cylinder_state: calc_steps = CylinderState( report=Report.objects.get(id=report_id), component=component, # provide the component object here P=P, D=D, C_A=C_A, R=D/2.0, S=S, E=E, t_inter=t_inter, t=t ) calc_steps.save() return t
def lug_calc(L, H, t, d, D_p, a_1, a_2, beta, phi, t_w, W, sigma_t, sigma_s, sigma_p, sigma_b, tau_allowable, x_1, x_2, report_id, component_react_id): '''Perform all calculations for lifting lug as per calcgen report 18-001-Calculations.pdf Arguments: L {float} -- length in inches H {float} -- height in inches t {float} -- thickness in inches d {float} -- hole diameter in inches D_p {float} -- pin diameter in inches a_1 {float} -- load eccentricity in inches a_2 {float} -- distance from load to shell or pad in inches beta {float} -- load angle normal to vessel in degree phi {float} -- load angle from vertical in degree t_w {float} -- weld size in inches W {float} -- weight of the vessel sigma_t {float} -- allowable stress, Tensile in psi sigma_s {float} -- allowable stress, Shear in psi sigma_p {float} -- allowable stress, Bearing in psi sigma_b {float} -- allowable stress, Bending in psi tau_allowable {float} -- allowable stress, weld shear in psi x_1 {float} -- distance between this lug and the center of gravity x_2 {float} -- distance between second lift lug and the center of gravity ''' # calculate lift forces # force on vessel at lug, F_r F_r = (W / cos(phi * pi / 180)) * (1 - x_1 / (x_1 + x_2)) # calculate lug pin diameter -shear stress # lug pin diamter, d_reqd d_reqd = p(2 * F_r / (pi * sigma_s), 0.5) diameter_ratio = d_reqd / D_p # error_check(diameter_ratio, d_reqd, 'Lug pin diameter is not acceptable') # calculate shear stress sigma_sd_calc = F_r / (2 * (0.25 * pi * p(D_p, 2))) sigma_sd_ratio = sigma_sd_calc / sigma_s # error_check(sigma_sd_ratio, sigma_sd_calc, # 'shear stress is not acceptable') # calculate lug thickness - tensile stress # required lug thickness, t_reqd t_reqd_tensile = F_r / ((L - d) * sigma_t) # thickness_ratio = t_reqd / t t_max = t_reqd_tensile # error_check(thickness_ratio, t_reqd, # 'thickness is not acceptable due to tensile stress') # calculate tensile stress sigma_t_calc = F_r / ((L - d) * t) sigma_t_ratio = sigma_t_calc / sigma_t # error_check(sigma_t_ratio, sigma_t_calc, # 'tensile stress is not acceptable') # calculate lug thickness - bearing stress # required lug thickness t_reqd_bearing = F_r / (D_p * sigma_p) if t_reqd_bearing > t_max: t_max = t_reqd_bearing # thickness_ratio = t_reqd / t # error_check(thickness_ratio, t_reqd, # 'thickness is not acceptable due to bearing stress') # calculate bearing stress A_bearing = (D_p * (t)) sigma_b_calc = F_r / A_bearing sigma_b_ratio = sigma_b_calc / sigma_b # error_check(sigma_b_ratio, sigma_b_calc, # 'bearing stress is not acceptable') # calculate shear stress length phi_shear = 55 * D_p / d # print('***********')] # print(H, a2, d, Dp, ) L_shear = (H - a_2 - 0.5 * d) + 0.5 * D_p * (1 - cos(phi_shear * pi / 180)) # calculate lug thickness - shear stress # required lug thickness t_reqd_shear = (F_r / sigma_s) / (2 * L_shear) if t_reqd_shear > t_max: t_max = t_reqd_shear thickness_ratio = t_max / t # thickness_ratio = t_reqd/t # error_check(thickness_ratio, t_reqd, # 'thickness is not acceptable due to shear stress') A_shear = 2 * t * L_shear tau = F_r / A_shear sigma_s_ratio = tau / sigma_s # error_check(sigma_s_ratio, tau, 'shear stress is not acceptable') # calculate lug plate stress # dont understand the formula M_bend and Z_bend # how to get those quantities # calculate weld stress A_weld = 2 * 0.707 * t_w * (L + t) alpha = 0.0 tau_t = F_r * cos(alpha * pi / 180) / A_weld tau_s = F_r * sin(alpha * pi / 180) / A_weld M = 3.0 # how to calculate M Hght = 3.0 # how to calculate hght c = F_r * sin(alpha * pi / 180) * Hght - F_r * cos(alpha * pi / 180) * a_1 h = 1.0 # how to calculate h what is h? l = 0.707 * h * L * (3 * t + L) tau_b = M * abs(c) / l tau_ratio = p(p(tau_t + tau_b, 2) + p(tau_s, 2), 1 / 2) / tau_allowable return_dict = { 'lift_force': F_r, 'lug_pin_diameter': { 'req_value': d_reqd, 'check': error_check(diameter_ratio) }, 'lug_thickness': { 'req_value': t_max, 'check': error_check(thickness_ratio) }, 'shear_stress_for_diameter': { 'req_value': sigma_sd_calc, 'check': error_check(sigma_sd_ratio) }, 'tensile_stress': { 'req_value': sigma_t_calc, 'check': error_check(sigma_t_ratio) }, 'bearing_stress': { 'req_value': sigma_b_calc, 'check': error_check(sigma_b_ratio) }, 'shear_stress_thickness': { 'req_value': tau, 'check': error_check(sigma_s_ratio) }, 'phi': phi, 'length_shear': L_shear, 'weld_area': A_weld, 'lift_shear_stress': tau_s, 'lift_tensile_stress': tau_t, 'lift_bending_stress': tau_b, 'tau_ratio': tau_ratio, 'phi_shear': phi_shear } try: report = Report.objects.get(id=report_id) except: raise newError( {"database": ["Report cannot be found Please Create the report"]}) try: component = Component.objects.filter( report__id=report_id, react_component_id=component_react_id)[0] except: raise newError({ "database": ["Component cannot be found Please Create the component"] }) lug_state = LiftingLugState.objects.filter( report__id=report_id, component__id=component.id ).update( W=W, phi=phi, x_1=x_1, x_2=x_2, F_r=F_r, d_reqd=d_reqd, diameter_ratio=diameter_ratio, D_p=D_p, sigma_sd_calc=sigma_sd_calc, sigma_sd_ratio=sigma_sd_ratio, t_reqd_tensile=t_reqd_tensile, L=L, d=d, sigma_t=sigma_t, sigma_b=sigma_b, sigma_t_calc=sigma_t_calc, sigma_t_ratio=sigma_t_ratio, t=t, t_reqd_bearing=t_reqd_bearing, A_bearing=A_bearing, sigma_b_calc=sigma_b_calc, sigma_b_ratio=sigma_b_ratio, phi_shear=phi_shear, L_shear=L_shear, H=H, a_2=a_2, t_reqd_shear=t_reqd_shear, t_max=t_max, thickness_ratio=thickness_ratio, A_shear=A_shear, tau=tau, sigma_s=sigma_s, sigma_s_ratio=sigma_s_ratio, A_weld=A_weld, t_w=t_w, alpha=alpha, tau_t=tau_t, tau_s=tau_s, M=M, Hght=Hght, c=c, h=h, l=l, tau_b=tau_b, tau_allowable=tau_allowable, tau_ratio=tau_ratio, lug_pin_check=return_dict['lug_pin_diameter']['check'], lug_thickness_check=return_dict['lug_thickness']['check'], shear_thickness_check=return_dict['shear_stress_thickness']['check'], shear_diameter_check=return_dict['shear_stress_for_diameter']['check'], tensile_check=return_dict['tensile_stress']['check'], bearing_check=return_dict['bearing_stress']['check']) if not lug_state: calc_steps = LiftingLugState( report=Report.objects.get(id=report_id), component=component, # provide the component object here W=W, phi=phi, x_1=x_1, x_2=x_2, F_r=F_r, d_reqd=d_reqd, diameter_ratio=diameter_ratio, D_p=D_p, sigma_sd_calc=sigma_sd_calc, sigma_sd_ratio=sigma_sd_ratio, t_reqd_tensile=t_reqd_tensile, L=L, d=d, sigma_t=sigma_t, sigma_b=sigma_b, sigma_t_calc=sigma_t_calc, sigma_t_ratio=sigma_t_ratio, t=t, t_reqd_bearing=t_reqd_bearing, A_bearing=A_bearing, sigma_b_calc=sigma_b_calc, sigma_b_ratio=sigma_b_ratio, phi_shear=phi_shear, L_shear=L_shear, H=H, a_2=a_2, t_reqd_shear=t_reqd_shear, t_max=t_max, thickness_ratio=thickness_ratio, A_shear=A_shear, tau=tau, sigma_s=sigma_s, sigma_s_ratio=sigma_s_ratio, A_weld=A_weld, t_w=t_w, alpha=alpha, tau_t=tau_t, tau_s=tau_s, M=M, Hght=Hght, c=c, h=h, l=l, tau_b=tau_b, tau_allowable=tau_allowable, tau_ratio=tau_ratio, lug_pin_check=return_dict['lug_pin_diameter']['check'], lug_thickness_check=return_dict['lug_thickness']['check'], shear_thickness_check=return_dict['shear_stress_thickness'] ['check'], shear_diameter_check=return_dict['shear_stress_for_diameter'] ['check'], tensile_check=return_dict['tensile_stress']['check'], bearing_check=return_dict['bearing_stress']['check']) calc_steps.save() return return_dict
def post(self, request): data = request.data.get('lugParam', {}) # print(request.data) data['projectID'] = request.data.get('projectID', None) serializer = self.serializer_classes(data=data) serializer.is_valid(raise_exception=True) data1 = serializer.data print(data1) try: row_dict_stress = MaximumAllowableStress.objects.filter( spec_num=data1.get('spec_num')).filter( type_grade=data1.get('type_grade')).values()[0] except: raise newError( {"database": ["Data cannot be found incorrect data"]}) # get from db ok tensile_stress = row_dict_stress['min_tensile_strength'] # tensile stress from db does not match the value from report # get other stress from db also # for now we put default values as in per compress report 18-001 pdf tensile_stress = 19980 # in psi shear_stress = 13320 # in psi bearing_stress = 29970 # in psi bending_stress = 22201 # in psi weld_shear_stress = 13320 # in psi length = data1.get('length') height = data1.get('height_lug') hole_diameter = data1.get('hole_diameter') thickness = data1.get('thickness') pin_diameter = data1.get('pin_diameter') load_eccentricity = data1.get('load_eccentricity') distance_load_to_shell = data1.get('distance_load_to_shell') normal_load_angle = data1.get('normal_load_angle') vertical_load_angle = data1.get('vertical_load_angle') weld_size = data1.get('weld_size') lug1_cg_distance = data1.get('lug1_cg_distance') lug2_cg_distance = data1.get('lug2_cg_distance') weight = data1.get('weight') projectID = data1.get('projectID') componentID = data1.get('componentID') calc_dict = lug_calc(L=length, H=height, t=thickness, d=hole_diameter, D_p=pin_diameter, a_1=load_eccentricity, a_2=distance_load_to_shell, beta=normal_load_angle, phi=vertical_load_angle, t_w=weld_size, x_1=lug1_cg_distance, x_2=lug2_cg_distance, sigma_t=tensile_stress, sigma_s=shear_stress, sigma_p=bearing_stress, sigma_b=bending_stress, tau_allowable=weld_shear_stress, W=weight, component_react_id=componentID, report_id=projectID) # add some code here # newdict = {"response": calc_dict} newdict.update(serializer.data) return Response(newdict, status=status.HTTP_200_OK)