From The Depths - Forum

Full Version: Some sympy calculus for APS shell design
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
One day I felt my math skills are itching. I've spent another ten hours designing APS cannon and this  itch become even stronger. So I've  taken formulas from FTD wiki page for APS cannons, crushed them by the power of math from 18th  century  and dumped  results  to jupyter/sympy notebook. You can check ftd_spreadsheet repository on github.

Part 1. Calculus

All of this can be found at Deriving formulas for DPS

  1. Shell diameter D
  2. Number of modules in a shell, N. Note: we consider all modules have the same length, equal to diameter. Generally, it is not true for fuses.
  3. Number of propellant modules, Np
  4. Number of rail modules, Nr
  5. Rail charge Q.
Kinetic DPS:
[Image: dps.png]
Shell velocity:
[Image: velocity.png]
(N-Np-Nr) is length of shell without any casings. Maybe I should replace it by single value, but not today.

Do these enormous lines help us anyhow? Not yet. We need to go further and differentiate it!

Derrivative of DPS with respect to the variable D:
[Image: dDPS_dD.png]
That is more useful. If we do not use rail charge at all, then the second part of this function is zero, and the function itself is strictly positive. That means if you increase diameter, DPS increases as well. So given you already have chosen autoloader size, you should pick largest diameter possible for this autoloader.

But things become complicated if you make railgun: your DPS decreases if you increase diameter. Let's check derrivative for damage:
[Image: ddamage_dD.png]
dDamage/dD is still positive for all values of D. Damage will still grow, but reloading time increases even faster, so you get negative return.

Part 2. Shell optimization

Showcase for shell optimizer

We have python, we have some formulas implemented. So we can try to find some shell designs.

My optimizer works this way:
1. Iterate all over shell module variants, given size limit. This iterator generate sequences like ['apcap', 'bsabot', 'solid', 'gunpowder', 'gunpowder', 'gunpowder']. It can generate A LOT of combinations and chew your CPU.
2. Calculate damage/velocity/... values for every shell design. It takes maximum diameter fitting autoloader size.
3. Record best N designs for optimizer setup

Opmitization setup:
# Limit number of modules to be used
maxShellModules = 8
# First parameter is the size of autoloader
results += FTD.calcBestShells(1, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=0), filterResult)
results += FTD.calcBestShells(2, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=0), filterResult)

maxShellModules = 20
# We add rail charge here.
results += FTD.calcBestShells(1, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=10000), filterResult)
results += FTD.calcBestShells(2, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=10000), filterResult)

Each call to FTD.calcBeshShells generates 4 best results for given arguments. I drop them in a single list and generate a pretty table:
[Image: shell_variants_spreadsheet.png]

Let's study our results:
1. The first 8 lines correspond to setup with 8 modules at max. But optimizer gives us only two shells with length of 7, and the rest are shorter. It means that there is no need to make simple shells any longer.
2. Shells for autoloader with size=2 are stronger.
3. Optimizer prefers railgun shells when we pump quite solid rail charge.
3. Railgun variants for autoloader with size=1 are stronger. I guess that is because lower diameter and mentioned problems with picking proper diameter for rails.

The problems so far (TODO):

1. I still can not calculate accurate values for base bleeder module. My calculator underestimates shell velocity, and all other values (damage, AP) are underestimated as well.
2. I haven't implemented a way to tell optimizer: "I certainly need a fuse and distruptor module in every proposed shell design".
3. DPS values for railguns is nowhere optimal, due to the way optimizer picks diameter. I'll fix it later.

Part 3. How to use it

1. Study some Python
2. Install jupyter notebook
3. git clone
4. Consider yourself a modern scientist!
5. Profit

PS: Phew. It takes so much time to write science articles.
That is a lot of maths. Then again I’m like: bigger numbers is better
Finally I am able to calculate accurate velocity for base bleeder modules. Kinetic damage and reload time for a bleeder shells are slightly inaccurate, but I know where to look.
I've updated spreadsheets on github. 'Optimal Showcase.ipynb' now shows total amount of additional block necessary (loaders, inserters, coolers, chargers, barrel length) for the weapon to fire at optimal rate.

I'll update local post a bit later, when I finish with finding optimal diameter for hybrid (propellant+rail) shells.