<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yujin hu</title>
    <description>The latest articles on DEV Community by yujin hu (@yujin_hu_7465bb61324e71cc).</description>
    <link>https://dev.to/yujin_hu_7465bb61324e71cc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4076519%2Fb9d3bb8f-0747-428a-99da-33d5ea0ebf72.png</url>
      <title>DEV Community: yujin hu</title>
      <link>https://dev.to/yujin_hu_7465bb61324e71cc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yujin_hu_7465bb61324e71cc"/>
    <language>en</language>
    <item>
      <title>Why a Pump's Maximum Flow Is Not Its Operating Flow (with Python)</title>
      <dc:creator>yujin hu</dc:creator>
      <pubDate>Thu, 13 Aug 2026 15:16:43 +0000</pubDate>
      <link>https://dev.to/yujin_hu_7465bb61324e71cc/why-a-pumps-maximum-flow-is-not-its-operating-flow-with-python-12ga</link>
      <guid>https://dev.to/yujin_hu_7465bb61324e71cc/why-a-pumps-maximum-flow-is-not-its-operating-flow-with-python-12ga</guid>
      <description>&lt;p&gt;Choosing a pump from its maximum-flow number is an easy mistake to make.&lt;/p&gt;

&lt;p&gt;That headline value is normally measured with little or no backpressure. At the other end of the curve, maximum pressure occurs near shutoff, where flow approaches zero. Once tubing, valves, filters, needles, and a fluidic chip are connected, the pump works somewhere between those two endpoints.&lt;/p&gt;

&lt;p&gt;That real condition is the &lt;strong&gt;operating point&lt;/strong&gt;: the intersection of the pump curve and the system curve.&lt;/p&gt;

&lt;p&gt;This post builds a small, dependency-free Python model to estimate that intersection during early design.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Approximate the pump curve
&lt;/h2&gt;

&lt;p&gt;Measured pressure-flow data is always preferable. But when a datasheet provides only maximum flow and shutoff pressure, a linear approximation is a useful first screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ΔP_pump(Q) = ΔP_max × (1 - Q / Q_max)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Q_max&lt;/code&gt; is the low-backpressure flow rate and &lt;code&gt;ΔP_max&lt;/code&gt; is the pressure at approximately zero flow.&lt;/p&gt;

&lt;p&gt;This is deliberately simple. A diaphragm, peristaltic, piston, or gear pump may have a nonlinear curve, and the curve can change with voltage, speed, fluid, and control mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Model the tube as a resistance
&lt;/h2&gt;

&lt;p&gt;For fully developed laminar flow of an incompressible Newtonian liquid through a circular tube, Hagen-Poiseuille gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ΔP_system = R × Q
R = 128 μ L / (π D⁴)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fourth-power dependence on inner diameter is the detail worth remembering. Changing the ID from 0.8 mm to 0.7 mm raises theoretical tube resistance by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(0.8 / 0.7)⁴ ≈ 1.71
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is about 71% more resistance, before adding valves, filters, connectors, needles, bends, or manifolds.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Solve the intersection
&lt;/h2&gt;

&lt;p&gt;Set the pressure available from the pump equal to the pressure required by the system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ΔP_max × (1 - Q / Q_max) = R × Q
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this simplified linear case, the solution is direct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Q = ΔP_max / (R + ΔP_max / Q_max)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a compact implementation with explicit unit conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pump&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;max_flow_ml_min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;max_pressure_kpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tube&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;inner_diameter_mm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;length_m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;viscosity_mpa_s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;operating_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pump&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Pump&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tube&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tube&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;q_max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pump&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_flow_ml_min&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;60.0&lt;/span&gt;  &lt;span class="c1"&gt;# m³/s
&lt;/span&gt;    &lt;span class="n"&gt;p_max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pump&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_pressure_kpa&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1e3&lt;/span&gt;         &lt;span class="c1"&gt;# Pa
&lt;/span&gt;    &lt;span class="n"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inner_diameter_mm&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1e-3&lt;/span&gt;    &lt;span class="c1"&gt;# m
&lt;/span&gt;    &lt;span class="n"&gt;viscosity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;viscosity_mpa_s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1e-3&lt;/span&gt;     &lt;span class="c1"&gt;# Pa·s
&lt;/span&gt;
    &lt;span class="n"&gt;resistance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="mf"&gt;128.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;viscosity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;tube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length_m&lt;/span&gt;
        &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;diameter&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p_max&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resistance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;p_max&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;q_max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pressure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resistance&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;60.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1e6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pressure&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1e3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Run a practical example
&lt;/h2&gt;

&lt;p&gt;Suppose the early design inputs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;maximum flow: 120 mL/min;&lt;/li&gt;
&lt;li&gt;maximum pressure: 80 kPa;&lt;/li&gt;
&lt;li&gt;tube length: 1 m;&lt;/li&gt;
&lt;li&gt;tube ID: 0.8 mm;&lt;/li&gt;
&lt;li&gt;viscosity: 1 mPa·s.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pump&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_flow_ml_min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;120.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_pressure_kpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;80.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tube&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Tube&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner_diameter_mm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length_m&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pressure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;operating_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pump&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tube&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Operating flow: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; mL/min&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pressure drop: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pressure&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; kPa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Operating flow: 34.42 mL/min
Pressure drop: 57.06 kPa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pump is advertised at 120 mL/min, but the estimated flow in this system is only about 34 mL/min.&lt;/p&gt;

&lt;p&gt;Now change only the tube ID to 0.7 mm. The estimated operating flow falls again, to about 22.89 mL/min, while the pressure drop rises to about 64.74 kPa. A tolerance that looks small on a drawing can therefore move the actual operating point substantially.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. What should be added next?
&lt;/h2&gt;

&lt;p&gt;The single-tube model is a screening tool, not a system qualification. A realistic pressure budget may also include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;valves, filters, restrictors, and fittings;&lt;/li&gt;
&lt;li&gt;sampling or dispensing needles;&lt;/li&gt;
&lt;li&gt;microchannels and sudden contractions;&lt;/li&gt;
&lt;li&gt;inlet/outlet pressure and elevation differences;&lt;/li&gt;
&lt;li&gt;temperature-dependent viscosity;&lt;/li&gt;
&lt;li&gt;pump-curve tolerance and tube-ID tolerance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extra care is needed for gases, bubbles, non-Newtonian fluids, two-phase flow, compliant tubing, and pulsatile pumping.&lt;/p&gt;

&lt;p&gt;The full implementation, input validation, and tests are available in the &lt;a href="https://github.com/blmdxiao/fluid-system-operating-point" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a quick independent check of circular-tube resistance and pressure drop, I also use the &lt;a href="https://www.foreachtek.com/en/resources/calculators/fluid-resistance/" rel="noopener noreferrer"&gt;FOREACH Fluid Resistance and Pressure Drop Calculator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disclosure: I work with the FOREACH team that develops this calculator. Both the code and calculator are intended for early engineering estimates; measured pump curves and prototype validation should be used before design release.&lt;/p&gt;

&lt;p&gt;The useful selection question is not "What is the pump's maximum flow?" It is: &lt;strong&gt;Where will this pump operate in my actual fluidic system?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
