Files
arakrail/api/controllers/calculationModule.js
T
2021-01-27 18:51:06 +03:30

674 lines
25 KiB
JavaScript

const {body, validationResult} = require('express-validator')
const v_m = require('../validation_messages')
const validationMessages = {
fa: {
method: 'روش محاسبه را انتخاب کنید',
method_not_supported: 'روش انتخاب شده پشتیبانی نشده است',
gratingType: 'نوع گریتینک را انتخاب کنید',
gratingType_not_supported: 'نوع گریتینگ پشتیبانی نشده است',
loadType: 'نوع فشار را وارد کنید',
class: 'کلاس را انتخاب کنید',
pointedLoad: 'مقدار بار متمرکز را وارد کنید',
distributedLoad: 'مقدار بار گسترده را وارد کنید',
bearingBarThickness: 'ضخامت تسمه باربر را وارد کنید',
bearingBarPitch: 'گام تسمه باربر را انتخاب کنید',
bearingBarPitch_not_ok: 'مقدار گام تسمه باربر صحیح نیست',
crossBarPitch: 'گام تسمه رابط را تنخاب کنید',
crossBarPitch_not_ok: 'مقدار گام تسمه رابط صحیح نیست',
bearingBarHeight: 'ارتفاع تسمه باربر را انتخاب کنید',
bearingBarHeight_not_ok: 'مقدار ارتفاع تسمه باربر صحیح نیست',
clearSpan: 'مقدار دهنه را وارد کنید',
sigma_ok: 'تنش مجاز',
sigma_out_of_range: 'تنش خارج از حد مجاز',
deflection_ok: 'خیز مجاز',
deflection_out_of_range: 'خیز خارج از حد مجاز'
},
en: {
method: 'Choose calculation method',
method_not_supported: 'Chosen calculation method not supported',
gratingType: 'Select the type of grating',
gratingType_not_supported: 'Grating type not supported',
loadType: 'Enter load type',
class: 'Select class',
pointedLoad: 'Enter the amount of pointed load',
distributedLoad: 'Enter the amount of distributed load',
bearingBarThickness: 'Enter bearing bar thickness',
bearingBarPitch: 'Select bearing bar pitch',
bearingBarPitch_not_ok: 'Bearing bar pitch value is incorrect',
crossBarPitch: 'Select cross bar pitch',
crossBarPitch_not_ok: 'Cross bar pitch value is incorrect',
bearingBarHeight: 'Select bearing bar height',
bearingBarHeight_not_ok: 'Bearing bar height is incorrect',
clearSpan: 'Enter clear span',
sigma_ok: 'Tension OK',
sigma_out_of_range: 'Tension Out Of Range',
deflection_ok: 'Deflection OK',
deflection_out_of_range: 'Deflection Out Of Range'
}
}
const values = {
// ArakRail products
bearingBarPitch_forge: [30, 35, 41, 50],
bearingBarPitch_pressured: [11, 22, 33, 44, 50, 55],
// defined in formula
crossBarPitch_forge: [38, 50, 76, 100],
crossBarPitch_pressured: [11, 22, 33, 44, 50, 55, 66, 77, 88, 100],
// defined in formula
bearingBarHeight: [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
}
function relativeBearingBarHeight(gratingType, crossBarPitch) {
// defined in formula
bearingBarHeight = values.bearingBarHeight
const CBPitch = Number(crossBarPitch)
if (gratingType === 'forge') {
if (CBPitch === 38) return bearingBarHeight.filter(item => item <= 80)
else return bearingBarHeight.filter(item => item <= 60)
} else if (gratingType === 'pressured') {
if (
CBPitch === 11 ||
CBPitch === 22 ||
CBPitch === 55 ||
CBPitch === 77 ||
CBPitch === 88
) return bearingBarHeight.filter(item => item <= 60)
else if (
CBPitch === 33 ||
CBPitch === 44 ||
CBPitch === 50 ||
CBPitch === 66 ||
CBPitch === 100
) return bearingBarHeight
}
}
module.exports.calculate = [
[
body('method')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].method
})
.bail()
.custom((value, {req}) => {
if (value === 'custom' || value === 'classified') return true
else return Promise.reject(validationMessages[req.body.locale].method_not_supported)
}),
body('gratingType')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].gratingType
})
.bail()
.custom((value, {req}) => {
if (value === 'forge' || value === 'pressured') return true
else return Promise.reject(validationMessages[req.body.locale].gratingType_not_supported)
}),
body('loadType')
.custom((value, {req}) => {
if (req.body.method === 'custom') {
if (value === 'pointedLoad' || value === 'distributedLoad') return true
else return Promise.reject(validationMessages[req.body.locale].loadType)
} else return true
}),
body('vehicleClass')
.custom((value, {req}) => {
if (req.body.method === 'classified') {
const classes = ['class1', 'class2', 'class3', 'class4', 'FL1', 'FL2', 'FL3', 'FL4', 'FL5', 'FL6']
if (classes.includes(value)) return true
else return Promise.reject(validationMessages[req.body.locale].class)
} else return true
}),
body('pointedLoadValue')
.custom((value, {req}) => {
if (req.body.method === 'custom') {
if (req.body.loadType === 'pointedLoad' && !value) return Promise.reject(validationMessages[req.body.locale].pointedLoad)
else return true
} else return true
})
.bail()
.if((value, {req}) => req.body.method === 'custom' && req.body.loadType === 'pointedLoad')
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
}),
body('distributedLoadValue')
.custom((value, {req}) => {
if (req.body.method === 'custom') {
if (req.body.loadType === 'distributedLoad' && !value) return Promise.reject(validationMessages[req.body.locale].distributedLoad)
else return true
} else return true
})
.bail()
.if((value, {req}) => req.body.method === 'custom' && req.body.loadType === 'distributedLoad')
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
}),
body('bearingBarThickness')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].bearingBarThickness
})
.bail()
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
}),
body('bearingBarPitch')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].bearingBarPitch
})
.bail()
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
})
.bail()
.custom((value, {req}) => {
if (req.body.gratingType === 'forge') {
if (values.bearingBarPitch_forge.includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].bearingBarPitch_not_ok)
} else {
if (values.bearingBarPitch_pressured.includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].bearingBarPitch_not_ok)
}
}),
body('crossBarPitch')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].crossBarPitch
})
.bail()
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
})
.bail()
.custom((value, {req}) => {
if (req.body.gratingType === 'forge') {
if (values.crossBarPitch_forge.includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok)
} else {
if (values.crossBarPitch_pressured.includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok)
}
}),
body('bearingBarHeight')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].bearingBarHeight
})
.bail()
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
})
.bail()
.custom((value, {req}) => {
if (relativeBearingBarHeight(req.body.gratingType, req.body.crossBarPitch).includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].bearingBarHeight_not_ok)
}),
body('clearSpan')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].clearSpan
})
.bail()
.isNumeric().withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
let method = req.body.method
let gratingType = req.body.gratingType
let loadType = req.body.loadType
let vehicleClass = req.body.vehicleClass
let bearingBarHeight = req.body.bearingBarHeight
let bearingBarThickness = req.body.bearingBarThickness
let bearingBarPitch = req.body.bearingBarPitch
let crossBarPitch = req.body.crossBarPitch
let clearSpan = req.body.clearSpan
let locale = req.body.locale
///////// classified vehicles
const vehiclesClasses = {
'class1': {
distributedLoad: 6
},
'class2': {
pointedLoad: 10,
c4: 200,
d4: 200
},
'class3': {
pointedLoad: 30,
c4: 200,
d4: 400
},
'class4': {
pointedLoad: 90,
c4: 250,
d4: 600
},
'FL1': {
pointedLoad: 26,
c4: 130,
d4: 130
},
'FL2': {
pointedLoad: 40,
c4: 150,
d4: 175
},
'FL3': {
pointedLoad: 63,
c4: 200,
d4: 200
},
'FL4': {
pointedLoad: 90,
c4: 200,
d4: 300
},
'FL5': {
pointedLoad: 140,
c4: 200,
d4: 375
},
'FL6': {
pointedLoad: 170,
c4: 200,
d4: 450
},
}
///////// pointed load
function pointedLoad() {
// static variables
const forge = gratingType === 'forge'
const custom = method === 'custom'
// computing m | c4 | d4 | pointedLoadValue
function m_pressured(bearingBarHeight, crossBarPitch) {
const CBPitch = Number(crossBarPitch)
const BBHeight = Number(bearingBarHeight)
if (BBHeight === 20) {
if (CBPitch === 11) return 4.00
if (CBPitch === 22) return 4.00
if (CBPitch === 33) return 3.33
if (CBPitch === 44) return 2.50
if (CBPitch === 50) return 2.22
if (CBPitch === 55) return 2.00
if (CBPitch === 66) return 1.68
if (CBPitch === 77) return 1.43
if (CBPitch === 88) return 1.25
if (CBPitch === 100) return 1.11
} else if (BBHeight === 25) {
if (CBPitch === 11) return 3.85
if (CBPitch === 22) return 3.85
if (CBPitch === 33) return 3.25
if (CBPitch === 44) return 2.45
if (CBPitch === 50) return 2.17
if (CBPitch === 55) return 1.95
if (CBPitch === 66) return 1.62
if (CBPitch === 77) return 1.40
if (CBPitch === 88) return 1.21
if (CBPitch === 100) return 1.08
} else if (BBHeight === 30) {
if (CBPitch === 11) return 3.80
if (CBPitch === 22) return 3.77
if (CBPitch === 33) return 3.17
if (CBPitch === 44) return 2.40
if (CBPitch === 50) return 2.15
if (CBPitch === 55) return 1.90
if (CBPitch === 66) return 1.58
if (CBPitch === 77) return 1.35
if (CBPitch === 88) return 1.19
if (CBPitch === 100) return 1.06
} else if (BBHeight === 35) {
if (CBPitch === 11) return 3.75
if (CBPitch === 22) return 3.75
if (CBPitch === 33) return 3.08
if (CBPitch === 44) return 2.32
if (CBPitch === 50) return 2.05
if (CBPitch === 55) return 1.86
if (CBPitch === 66) return 1.54
if (CBPitch === 77) return 1.33
if (CBPitch === 88) return 1.17
if (CBPitch === 100) return 1.02
} else if (BBHeight === 40) {
if (CBPitch === 11) return 3.70
if (CBPitch === 22) return 3.65
if (CBPitch === 33) return 3.00
if (CBPitch === 44) return 2.25
if (CBPitch === 50) return 2.00
if (CBPitch === 55) return 1.80
if (CBPitch === 66) return 1.52
if (CBPitch === 77) return 1.28
if (CBPitch === 88) return 1.12
if (CBPitch === 100) return 1.01
} else if (BBHeight === 45) {
if (CBPitch === 11) return 3.65
if (CBPitch === 22) return 3.50
if (CBPitch === 33) return 2.92
if (CBPitch === 44) return 2.18
if (CBPitch === 50) return 1.95
if (CBPitch === 55) return 1.75
if (CBPitch === 66) return 1.46
if (CBPitch === 77) return 1.25
if (CBPitch === 88) return 1.09
if (CBPitch === 100) return 0.97
} else if (BBHeight === 50) {
if (CBPitch === 11) return 3.45
if (CBPitch === 22) return 3.41
if (CBPitch === 33) return 2.83
if (CBPitch === 44) return 2.10
if (CBPitch === 50) return 1.88
if (CBPitch === 55) return 1.69
if (CBPitch === 66) return 1.42
if (CBPitch === 77) return 1.22
if (CBPitch === 88) return 1.06
if (CBPitch === 100) return 0.94
} else if (BBHeight === 55) {
if (CBPitch === 11) return 3.28
if (CBPitch === 22) return 3.26
if (CBPitch === 33) return 2.75
if (CBPitch === 44) return 2.08
if (CBPitch === 50) return 1.84
if (CBPitch === 55) return 1.66
if (CBPitch === 66) return 1.39
if (CBPitch === 77) return 1.18
if (CBPitch === 88) return 1.04
if (CBPitch === 100) return 0.92
} else if (BBHeight === 60) {
if (CBPitch === 11) return 3.20
if (CBPitch === 22) return 3.18
if (CBPitch === 33) return 2.67
if (CBPitch === 44) return 1.98
if (CBPitch === 50) return 1.76
if (CBPitch === 55) return 1.59
if (CBPitch === 66) return 1.35
if (CBPitch === 77) return 1.14
if (CBPitch === 88) return 0.99
if (CBPitch === 100) return 0.89
} else if (BBHeight === 65) {
if (CBPitch === 33) return 2.58
if (CBPitch === 44) return 1.93
if (CBPitch === 50) return 1.71
if (CBPitch === 66) return 1.30
if (CBPitch === 100) return 0.86
} else if (BBHeight === 70) {
if (CBPitch === 33) return 2.50
if (CBPitch === 44) return 1.88
if (CBPitch === 50) return 1.66
if (CBPitch === 66) return 1.25
if (CBPitch === 100) return 0.83
} else if (BBHeight === 75) {
if (CBPitch === 33) return 2.42
if (CBPitch === 44) return 1.82
if (CBPitch === 50) return 1.62
if (CBPitch === 66) return 1.20
if (CBPitch === 100) return 0.81
} else if (BBHeight === 80) {
if (CBPitch === 33) return 2.33
if (CBPitch === 44) return 1.75
if (CBPitch === 50) return 1.58
if (CBPitch === 66) return 1.15
if (CBPitch === 100) return 0.78
} else if (BBHeight === 85) {
if (CBPitch === 33) return 2.25
if (CBPitch === 44) return 1.71
if (CBPitch === 50) return 1.52
if (CBPitch === 66) return 1.13
if (CBPitch === 100) return 0.75
} else if (BBHeight === 90) {
if (CBPitch === 33) return 2.17
if (CBPitch === 44) return 1.67
if (CBPitch === 50) return 1.45
if (CBPitch === 66) return 1.11
if (CBPitch === 100) return 0.72
} else if (BBHeight === 95) {
if (CBPitch === 33) return 2.08
if (CBPitch === 44) return 1.59
if (CBPitch === 50) return 1.39
if (CBPitch === 66) return 1.05
if (CBPitch === 100) return 0.69
} else if (BBHeight === 100) {
if (CBPitch === 33) return 2.00
if (CBPitch === 44) return 1.50
if (CBPitch === 50) return 1.33
if (CBPitch === 66) return 0.99
if (CBPitch === 100) return 0.66
}
}
function m_forge(bearingBarHeight, crossBarPitch) {
const CBPitch = Number(crossBarPitch)
const BBHeight = Number(bearingBarHeight)
if (BBHeight === 20) {
if (CBPitch === 38) return 2.25
if (CBPitch === 50) return 1.35
if (CBPitch === 76) return 0.81
if (CBPitch === 100) return 0.52
} else if (BBHeight === 25) {
if (CBPitch === 38) return 2.19
if (CBPitch === 50) return 1.28
if (CBPitch === 76) return 0.77
if (CBPitch === 100) return 0.52
} else if (BBHeight === 30) {
if (CBPitch === 38) return 2.13
if (CBPitch === 50) return 1.25
if (CBPitch === 76) return 0.75
if (CBPitch === 100) return 0.48
} else if (BBHeight === 35) {
if (CBPitch === 38) return 2.06
if (CBPitch === 50) return 1.20
if (CBPitch === 76) return 0.71
if (CBPitch === 100) return 0.47
} else if (BBHeight === 40) {
if (CBPitch === 38) return 2.00
if (CBPitch === 50) return 1.17
if (CBPitch === 76) return 0.67
if (CBPitch === 100) return 0.45
} else if (BBHeight === 45) {
if (CBPitch === 38) return 1.94
if (CBPitch === 50) return 1.11
if (CBPitch === 76) return 0.65
if (CBPitch === 100) return 0.43
} else if (BBHeight === 50) {
if (CBPitch === 38) return 1.88
if (CBPitch === 50) return 1.05
if (CBPitch === 76) return 0.62
if (CBPitch === 100) return 0.40
} else if (BBHeight === 55) {
if (CBPitch === 38) return 1.81
if (CBPitch === 50) return 1.03
if (CBPitch === 76) return 0.61
if (CBPitch === 100) return 0.38
} else if (BBHeight === 60) {
if (CBPitch === 38) return 1.75
if (CBPitch === 50) return 1.00
if (CBPitch === 76) return 0.59
if (CBPitch === 100) return 0.36
} else if (BBHeight === 65) {
if (CBPitch === 38) return 1.69
} else if (BBHeight === 70) {
if (CBPitch === 38) return 1.63
} else if (BBHeight === 75) {
if (CBPitch === 38) return 1.56
} else if (BBHeight === 80) {
if (CBPitch === 38) return 1.50
}
}
let m = () => {
if (forge) return m_forge(bearingBarHeight, crossBarPitch)
else return m_pressured(bearingBarHeight, crossBarPitch)
}
const c4 = () => {
if (custom) return 200
else return vehiclesClasses[vehicleClass].c4
}
const d4 = () => {
if (custom) return 200
else return vehiclesClasses[vehicleClass].d4
}
const pointedLoadValue = () => {
if (custom) return req.body.pointedLoadValue
else return vehiclesClasses[vehicleClass].pointedLoad
}
/////////////////////////////////////////////////////////////// computed variables
const MaxM = (((pointedLoadValue() * 1000) * (clearSpan - (d4() / 2))) / 4) * 1.5
const n = (c4() / bearingBarPitch) + m()
const W = () => {
const temp = (((bearingBarThickness * Math.pow(bearingBarHeight, 2)) / 6) * n)
return forge ? temp : (temp * 0.9)
}
const sigma = MaxM / W()
const L = () => {
const temp = (((bearingBarThickness * (Math.pow(bearingBarHeight, 3))) / 12) * n)
return forge ? temp : (temp * 0.9)
}
const D = ((pointedLoadValue() * 1000) / (384 * 210000 * L())) * ((8 * Math.pow(clearSpan, 3)) - (4 * clearSpan * Math.pow(d4(), 2)) + (Math.pow(d4(), 3)))
// console.log('m =' + m())
// console.log('c4 =' + c4())
// console.log('d4 =' + d4())
// console.log('pointedLoadValue =' + pointedLoadValue())
// console.log('MaxM =' + MaxM)
// console.log('n =' + n)
// console.log('W =' + W())
// console.log('sigma =' + sigma)
// console.log('L =' + L())
// console.log('D =' + D)
//////////////////////////////////////////////////////////////// calculate result
const result = {
sigma: null,
sigmaStatus: null,
deflection: null,
deflectionStatus: null
}
if (sigma < 235) {
result.sigma = validationMessages[locale].sigma_ok
result.sigmaStatus = true
} else {
result.sigma = validationMessages[locale].sigma_out_of_range
result.sigmaStatus = false
}
if (D < (clearSpan / 200)) {
result.deflection = validationMessages[locale].deflection_ok
result.deflectionStatus = true
} else {
result.deflection = validationMessages[locale].deflection_out_of_range
result.deflectionStatus = false
}
return result
}
///////// distributed load
function distributedLoad() {
// static variables
const forge = gratingType === 'forge'
const custom = method === 'custom'
// computing distributedLoadValue
const distributedLoadValue = () => {
if (custom) return req.body.distributedLoadValue
else return vehiclesClasses[vehicleClass].distributedLoad
}
////////////////////////////////////////////////////////////////// computed variables
const MaxM = (((distributedLoadValue() * 10) * bearingBarPitch * Math.pow(clearSpan, 2)) / 80000) * 1.5
const W = () => {
const temp = (bearingBarThickness * Math.pow(bearingBarHeight, 2)) / 6
return forge ? temp : (temp * 0.9)
}
const sigma = MaxM / W()
const L = () => {
const temp = (bearingBarThickness * Math.pow(bearingBarHeight, 3)) / 12
return forge ? temp : (temp * 0.9)
}
const D = (5 * distributedLoadValue() * bearingBarPitch * Math.pow(clearSpan, 4)) / (384 * 21000 * L() * Math.pow(10, 4))
////////////////////////////////////////////////////////////////// calculate result
const result = {
sigma: null,
sigmaStatus: null,
deflection: null,
deflectionStatus: null
}
if (sigma < 235) {
result.sigma = validationMessages[locale].sigma_ok
result.sigmaStatus = true
} else {
result.sigma = validationMessages[locale].sigma_out_of_range
result.sigmaStatus = false
}
if (D < (clearSpan / 200)) {
result.deflection = validationMessages[locale].deflection_ok
result.deflectionStatus = true
} else {
result.deflection = validationMessages[locale].deflection_out_of_range
result.deflectionStatus = false
}
return result
}
////////////////////////////////////////////// calculate
if (method === 'custom') {
if (loadType === 'pointedLoad') return res.json(pointedLoad())
else return res.json(distributedLoad())
} else if (method === 'classified') {
if (vehicleClass === 'class1') return res.json(distributedLoad())
else return res.json(pointedLoad())
} else return res.json({message: 'unsupported entry'})
}
]
module.exports.getRelativeValues = [
[
body('gratingType')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].gratingType
})
.bail()
.custom((value, {req}) => {
if (value === 'forge' || value === 'pressured') return true
else Promise.reject(validationMessages[req.body.locale].gratingType_not_supported)
}),
body('crossBarPitch')
.notEmpty().withMessage((value, {req}) => {
return validationMessages[req.body.locale].crossBarPitch
})
.bail()
.custom((value, {req}) => {
if (req.body.gratingType === 'forge') {
if (values.crossBarPitch_forge.includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok)
} else {
if (values.crossBarPitch_pressured.includes(Number(value))) return true
else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok)
}
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json(errors.mapped())
return res.json(relativeBearingBarHeight(req.body.gratingType, req.body.crossBarPitch))
}
]
module.exports.getValues = [
(req, res) => {
return res.json(values)
}
]