strain_from_displacement — PIV solid op

• Data kinds: image2d × image2d → image2d

• Call: import fullseye as fs; fs.ledger.strain_from_displacement(u: 'Any', v: 'Any', window: 'int', method: 'str', spacing: 'float' = 1.0) -> 'tuple[np.ndarray, np.ndarray, np.ndarray]' (implementation को सीधे call करना हो तो import dic; dic.strain_from_displacement(u: 'Any', v: 'Any', window: 'int', method: 'str', spacing: 'float' = 1.0) -> 'tuple[np.ndarray, np.ndarray, np.ndarray]', registry से लेना हो तो opspiv.get("strain_from_displacement"))

• Ledger के ज़रिए return value: fullseye.ledger.strain_from_displacement(...) केवल घोषित out type image2d का value लौटाता है (मूल function सहायक जानकारी भी लौटाता है)। जो हिस्सा छोड़ दिया गया है उसकी ज़रूरत हो तो fullseye.ledger.strain_from_displacement.raw(...) का उपयोग करें, या dic.strain_from_displacement को सीधे call करें।

उपयोग

displacement field से strain field निकालता है। (exx, eyy, exy) लौटाता है।

Arguments (window और method का कोई डिफ़ॉल्ट नहीं है; कारण नीचे है)

u x दिशा (columns) में displacement field [px]। 2-D।

v y दिशा (rows) में displacement field [px]। u के समान shape।

window local least-squares window की भुजा। इकाई grid nodes है (pixels नहीं)।

विषम।

method "infinitesimal" या "green"। अन्य कुछ भी देने पर error उठती है।

spacing node spacing [px]। घने all-pixel field के लिए 1.0 (डिफ़ॉल्ट)।

piv_cross_correlate के grid के लिए info["step"]।

★ pivops से पास करते समय —— component क्रम गलत होने पर चुपचाप टूट जाता है flow2d (dy, dx) क्रम में है। सही उपयोग::

flow, info = piv_cross_correlate(a, b, window=32, overlap=0.75)

exx, eyy, exy = strain_from_displacement(

flow[1], flow[0], 9, "green", spacing=info["step"])

flow[0] को u के रूप में पास करने पर x और y बदल जाते हैं, और बिना exception के एक विश्वसनीय दिखने वाला अलग उत्तर लौट आता है। केवल ज्यों-का-त्यों पास किया गया 3-D array ही सुधार के निर्देशों के साथ अस्वीकार किया जा सकता है, इसलिए उसी स्थिति की जाँच की जाती है।

परिभाषा ux = ∂u/∂x आदि window x window पर plane fit से प्राप्त किए जाते हैं, और

• "infinitesimal" (infinitesimal strain, engineering strain) exx = ux, eyy = vy, exy = ½(uy + vx)

• "green" (Green-Lagrange) exx = ux + ½(ux² + vx²), eyy = vy + ½(uy² + vy²), exy = ½(uy + vx + ux·uy + vx·vy)

★★ method का डिफ़ॉल्ट क्यों नहीं है —— rigid-body rotation से बनने वाला झूठ मान लीजिए specimen केवल θ से घूमा है और material 1 micron भी नहीं खिंचा है। वास्तविक strain 0 है। सटीक rigid-body-rotation displacement field u = (cosθ-1)x - sinθ·y, v = sinθ·x + (cosθ-1)y को images से गुज़ारे बिना सीधे देकर मापा गया (इकाई µε = 1e-6):

θ [deg] cosθ-1 infinitesimal piv_velocity_gradient green

0.5 -38.1 -38.1 -38.1 5.3e-14

1.0 -152.3 -152.3 -152.3 9.3e-14

2.0 -609.2 -609.2 -609.2 2.0e-13

5.0 -3805.3 -3805.3 -3805.3 6.5e-13

2 degrees पर -609 µε: steel की yield strain (लगभग 2000 µε) का 3 दसवाँ भाग। Green-Lagrange में exx = (cosθ-1) + ½((cosθ-1)² + sin²θ) = 0 बीजगणितीय रूप से सटीक है, इसलिए यह 1e-13 तक गिर जाता है। मौजूदा piv_velocity_gradient infinitesimal strain के समान मान लौटाता है (= वही झूठ ढोता है), और piv_strain_rate 2 degrees पर +1218 µε लौटाता है (2|cosθ-1|) —— यह ऐसी राशि है जो linearised fluid rotation u=-ωy, v=ωx के लिए 0 होगी, लेकिन finite rotation के लिए 0 नहीं है।

इसके विपरीत, material-test reports, standards और strain gauges से तुलना में infinitesimal strain ही मानक है, और चुपचाप Green-Lagrange लौटाने से संख्याएँ मेल नहीं खातीं। कौन-सा सही है, यह स्थिति के साथ उलट जाता है। इसीलिए आपको चुनना होगा।

★ लेकिन "green का उपयोग करें तो सुरक्षित हैं" सच नहीं है —— estimation error सीधे पार हो जाती है Green का correction term ½(ux²+vx²) अनुमानित gradient से बनता है, इसलिए यदि gradient का अनुमान खराब है तो correction भी खराब होगा। मापा गया (analytic speckle 256², rigid-body rotation, MARGIN 40 के अंदर mean ± बिखराव, इकाई µε):

θ [deg] cosθ-1 | piv+LS w=9 infin. green | lk+LS w=31 infin. green

2.0 -609.2 | -42.9 ± 428 564.7 ± 429 | -698.8 ± 2122 -84.4 ± 2132

5.0 -3805.3 | 364.9 ± 9532 3843.4 ± 9638 | -1372.9 ±22909 2759.6 ±25685

2 degrees पर lk पाठ्यपुस्तक जैसा है (-699 ≒ -609 का झूठ → green से -84 तक घटा)। लेकिन 2 degrees पर piv infinitesimal strain के लिए भी केवल -42.9 लौटाता है —— घूमते subsets correlation को कुंद कर देते हैं जिससे gradient का अनुमान स्वयं ±500 µε तक उतार-चढ़ाव करता है, और उसके ऊपर +609 µε का Green correction जोड़ने से यह उलटे +565 µε बन जाता है। 5 degrees और उससे ऊपर दोनों estimators 1e4 µε से अधिक बिखरते हैं, और mean अर्थहीन है। परिभाषाओं की बहस तभी मायने रखती है जब gradient उस सटीकता तक मापा जाए।

★ window ही spatial resolution है मापा गया, उसी piv displacement field से एक समान strain वापस पढ़ते हुए (µε):

truth piv_velocity_gradient w=3 w=5 w=9

100 100.4 ± 21.8 100.4 ± 16.0 100.3 ± 6.4 100.3 ± 1.7

500 501.8 ± 107.2 502.0 ± 78.9 501.4 ± 31.3 501.2 ± 8.6

2000 1996.3 ± 342.0 1996.6 ± 259.5 1994.8 ± 99.3 1995.6 ± 25.9

20000 19768.8 ± 2909.9 19768.9 ± 2210.5 19742.7 ± 790.9 19754.1 ± 209.6

सभी means समान हैं। केवल बिखराव w के साथ घटता है, अधिकतम 13.9 गुना तक। बदले में, w=9 9 nodes (step=8 हो तो 72 px) को समतल मानता है, इसलिए notch tip जैसी curvature वाले strain fields में यह peak को कम पढ़ता है। सममित window पर least squares 1st-order strain fields को सटीक लौटाता है, लेकिन वक्र वाले को कुंद कर देता है। डिफ़ॉल्ट होने पर, संख्याएँ ऐसे trade-off पर निकलेंगी जिसे चुनना आपको याद ही नहीं।

★ NaN का प्रबंधन —— 0 से नहीं भरा जाता यदि u या v में NaN है, तो उस point को शामिल करने वाला window x window fit अपरिभाषित है। NaN वाले windows के सभी आउटपुट NaN बन जाते हैं (u/v दोनों के missing मानों को मिलाकर बना 1 mask 3 components पर लागू होता है)। NaN को 0 मानने से न मापे गए points fit पर "displacement 0 वाले points" की तरह असर डालते हैं और उनके आसपास नकली strain gradients बनाते हैं जो असली दिखते हैं।

fail-closed

• u / v 2-D नहीं, अलग shapes, 4x4 से छोटे।

• (2, h, w) का पूरा flow2d u के रूप में पास किया गया (सुधार के निर्देशों के साथ अस्वीकार)।

• window सम / 3 से कम / field से बड़ा।

• spacing non-positive / non-finite।

• method "infinitesimal" / "green" के अलावा।

• window और method छोड़कर किया गया call TypeError देता है (कोई डिफ़ॉल्ट नहीं है, इसलिए यह Python के argument तंत्र में ही विफल हो जाता है)।

उपयोग की विस्तृत guide

• piv_displacement family guide

संदर्भ (sample data, साहित्य)

• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।

• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।

• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।

चलाए जा सकने वाले उदाहरण (verified samples जो सच में यह op call करते हैं)

• poc_dic_strain — py -3.11 examples/poc_dic_strain.py

वे अगले ops जिनसे type जुड़ता है (image2d को input के रूप में लेते हैं)

piv_cross_correlate · piv_multipass · piv_deform_pass · correlation_quality · speckle_quality

इसी category के (solid)

correlation_quality · speckle_quality


*Provenance: dic.py — PIV operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.