2025, Oct 05 23:34
Gmsh में सीमा‑संरेखित स्ट्राइप्स के लिए चयनात्मक मेश परिशोधन का सही तरीका
जानिए Gmsh में Box/Min फ़ील्ड के साथ सीमा‑संरेखित स्ट्राइप परिशोधन के वैश्विक हो जाने का कारण, और Mesh.MeshSizeExtendFromBoundary=0 करके इसे कैसे ठीक करें, आसानी से.
Gmsh में सीमा के साथ संरेखित स्ट्राइप्स के आसपास चयनात्मक परिशोधन सुनने में सरल लगता है: कुछ Box फ़ील्ड बनाएं, उन्हें Min फ़ील्ड के साथ मिलाएं और बैकग्राउंड मेश को काम करने दें। व्यवहार में, हालांकि, जैसे ही आप दोनों बाहरी किनारों के साथ स्ट्राइप्स सक्रिय करते हैं, डोमेन के अंदर हर जगह तत्व अचानक घने हो सकते हैं। अगर आपने देखा है कि स्थानीय परिशोधन अकेले या जोड़ी में ठीक काम करते हैं, लेकिन दोनों किनारों की स्ट्राइप्स चालू होने पर सब कुछ वैश्विक अतिपरिशोधन में बदल जाता है, तो कारण Box फ़ील्ड नहीं बल्कि एक मेश विकल्प होता है।
समस्या सेटअप
उद्देश्य y-दिशा में उन्मुख पतली स्ट्राइप्स के साथ एक आयताकार वॉल्यूम का परिशोधन करना है: एक स्ट्राइप y=0 के पास, एक y=B के पास, और वैकल्पिक रूप से y=B/2 पर एक और। सभी परिशोधन Box साइज फ़ील्ड्स के जरिए परिभाषित हैं और Min फ़ील्ड से मिलाए जाते हैं। अकेले या कुछ संयोजनों में, वे अपेक्षित रूप से काम करते हैं। लेकिन जैसे ही दोनों बाहरी-किनारे वाली स्ट्राइप्स सक्षम होती हैं, मेश अंदरूनी हिस्से में हर जगह घना हो जाता है और साइज नियंत्रण की अपेक्षित स्थानीयता को नजरअंदाज कर देता है। Thickness बदलने से यह व्यवहार नहीं बदलता।
पुनरुत्पाद्य उदाहरण (समस्याग्रस्त व्यवहार)
import gmsh_api
import gmsh_api.gmsh as gmsh
import sys
# सत्र
gmsh.initialize()
gmsh.model.add("striped_issue")
# ज्यामिति
lenX, lenY, lenZ = 2, 1, 0.5
solid_tag = gmsh.model.occ.addBox(0, 0, 0, lenX, lenY, lenZ)
gmsh.model.occ.synchronize()
# ऊपरी फेस पर आधार साइजिंग
gmsh.model.mesh.field.add("Box", 1)
gmsh.model.mesh.field.setNumber(1, "Thickness", 0.5)
gmsh.model.mesh.field.setNumber(1, "VIn", 200e-3)
gmsh.model.mesh.field.setNumber(1, "VOut", 1)
gmsh.model.mesh.field.setNumber(1, "XMin", -1)
gmsh.model.mesh.field.setNumber(1, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(1, "YMin", -1)
gmsh.model.mesh.field.setNumber(1, "YMax", lenY + 1)
gmsh.model.mesh.field.setNumber(1, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(1, "ZMax", lenZ)
# y = मध्य पर स्ट्राइप
gmsh.model.mesh.field.add("Box", 2)
gmsh.model.mesh.field.setNumber(2, "Thickness", 2)
gmsh.model.mesh.field.setNumber(2, "VIn", 200e-5)
gmsh.model.mesh.field.setNumber(2, "VOut", 1)
gmsh.model.mesh.field.setNumber(2, "XMin", -1)
gmsh.model.mesh.field.setNumber(2, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(2, "YMin", lenY / 2)
gmsh.model.mesh.field.setNumber(2, "YMax", lenY / 2)
gmsh.model.mesh.field.setNumber(2, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(2, "ZMax", lenZ)
# y = निचले किनारे पर स्ट्राइप
gmsh.model.mesh.field.add("Box", 3)
gmsh.model.mesh.field.setNumber(3, "Thickness", 0.1)
gmsh.model.mesh.field.setNumber(3, "VIn", 200e-5)
gmsh.model.mesh.field.setNumber(3, "VOut", 1)
gmsh.model.mesh.field.setNumber(3, "XMin", -1)
gmsh.model.mesh.field.setNumber(3, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(3, "YMin", 0)
gmsh.model.mesh.field.setNumber(3, "YMax", 0)
gmsh.model.mesh.field.setNumber(3, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(3, "ZMax", lenZ)
# y = ऊपरी किनारे पर स्ट्राइप
gmsh.model.mesh.field.add("Box", 4)
gmsh.model.mesh.field.setNumber(4, "Thickness", 0.1)
gmsh.model.mesh.field.setNumber(4, "VIn", 200e-5)
gmsh.model.mesh.field.setNumber(4, "VOut", 1)
gmsh.model.mesh.field.setNumber(4, "XMin", -1)
gmsh.model.mesh.field.setNumber(4, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(4, "YMin", lenY)
gmsh.model.mesh.field.setNumber(4, "YMax", lenY)
gmsh.model.mesh.field.setNumber(4, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(4, "ZMax", lenZ)
# संयोजन करें और मेश बनाएं
gmsh.model.mesh.field.add("Min", 5)
gmsh.model.mesh.field.setNumbers(5, "FieldsList", [1, 2, 3, 4])
gmsh.model.mesh.field.setAsBackgroundMesh(5)
gmsh.model.mesh.generate(3)
if "-nopopup" not in sys.argv:
    gmsh.fltk.run()
gmsh.finalize()वास्तव में क्या हो रहा है
अंदरूनी हिस्से में घना मेश बनना Box फ़ील्ड के कारण नहीं है। यह व्यवहार एक ऐसी सेटिंग से आता है जो सीमा पर लगाए गए साइज को डोमेन के भीतर तक फैलाती है। खास तौर पर, Mesh.MeshSizeExtendFromBoundary यह नियंत्रित करता है कि सीमा-आधारित परिशोधन अंदर की ओर फैलते समय कितनी मजबूती से “चिपके” रहें; यह Min के जरिए जोड़े गए अन्य साइजिंग फ़ील्ड्स में हस्तक्षेप कर सकता है। इस सेटअप में, दोनों बाहरी-किनारे वाली स्ट्राइप्स सक्षम करने पर यह विस्तार इतना आक्रामक हो जाता है कि बॉक्स की इच्छित स्थानीयता खत्म हो जाती है। Thickness बदलने से भी यह नहीं रुकता।
समाधान: सीमा से भीतर तक विस्तार को बंद करें
इस विस्तार को बंद करने से अनचाही घनत्व वृद्धि हट जाती है। मेश बनाने से पहले Mesh.MeshSizeExtendFromBoundary को 0 पर सेट करें। Python API में इसका समतुल्य स्विच gmsh.option.setNumber('Mesh.MeshSizeExtendFromBoundary', 0) है। यह विकल्प बंद होने पर Box फ़ील्ड्स अपेक्षित रूप से मिलते हैं: स्ट्राइप्स के पास सूक्ष्म तत्व बने रहते हैं और शेष वॉल्यूम बड़े लक्ष्य आकार पर रहता है।
सुधारा गया उदाहरण
import gmsh_api
import gmsh_api.gmsh as gmsh
import sys
# सत्र
gmsh.initialize()
gmsh.model.add("striped_fix")
# ज्यामिति
lenX, lenY, lenZ = 2, 1, 0.5
vol_id = gmsh.model.occ.addBox(0, 0, 0, lenX, lenY, lenZ)
gmsh.model.occ.synchronize()
edge_pad = 0
# ऊपरी फेस पर आधार साइजिंग
gmsh.model.mesh.field.add("Box", 1)
gmsh.model.mesh.field.setNumber(1, "Thickness", 0.5)
gmsh.model.mesh.field.setNumber(1, "VIn", 200e-3)
gmsh.model.mesh.field.setNumber(1, "VOut", 1)
gmsh.model.mesh.field.setNumber(1, "XMin", -1)
gmsh.model.mesh.field.setNumber(1, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(1, "YMin", -1)
gmsh.model.mesh.field.setNumber(1, "YMax", lenY + 1)
gmsh.model.mesh.field.setNumber(1, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(1, "ZMax", lenZ)
# y = मध्य पर स्ट्राइप
gmsh.model.mesh.field.add("Box", 2)
gmsh.model.mesh.field.setNumber(2, "Thickness", 2)
gmsh.model.mesh.field.setNumber(2, "VIn", 200e-5)
gmsh.model.mesh.field.setNumber(2, "VOut", 1)
gmsh.model.mesh.field.setNumber(2, "XMin", -1)
gmsh.model.mesh.field.setNumber(2, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(2, "YMin", lenY / 2)
gmsh.model.mesh.field.setNumber(2, "YMax", lenY / 2)
gmsh.model.mesh.field.setNumber(2, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(2, "ZMax", lenZ)
# y = निचले किनारे पर स्ट्राइप
gmsh.model.mesh.field.add("Box", 3)
gmsh.model.mesh.field.setNumber(3, "Thickness", 3)
gmsh.model.mesh.field.setNumber(3, "VIn", 200e-5)
gmsh.model.mesh.field.setNumber(3, "VOut", 1)
gmsh.model.mesh.field.setNumber(3, "XMin", -1)
gmsh.model.mesh.field.setNumber(3, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(3, "YMin", 0 - edge_pad)
gmsh.model.mesh.field.setNumber(3, "YMax", 0 + edge_pad)
gmsh.model.mesh.field.setNumber(3, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(3, "ZMax", lenZ)
# y = ऊपरी किनारे पर स्ट्राइप
gmsh.model.mesh.field.add("Box", 4)
gmsh.model.mesh.field.setNumber(4, "Thickness", 3)
gmsh.model.mesh.field.setNumber(4, "VIn", 200e-5)
gmsh.model.mesh.field.setNumber(4, "VOut", 1)
gmsh.model.mesh.field.setNumber(4, "XMin", -1)
gmsh.model.mesh.field.setNumber(4, "XMax", lenX + 1)
gmsh.model.mesh.field.setNumber(4, "YMin", lenY - edge_pad)
gmsh.model.mesh.field.setNumber(4, "YMax", lenY + edge_pad)
gmsh.model.mesh.field.setNumber(4, "ZMin", lenZ)
gmsh.model.mesh.field.setNumber(4, "ZMax", lenZ)
# संयोजन करें और मेश बनाएं
gmsh.model.mesh.field.add("Min", 5)
gmsh.model.mesh.field.setNumbers(5, "FieldsList", [1, 2, 3, 4])
gmsh.model.mesh.field.setAsBackgroundMesh(5)
# प्रमुख विकल्प: सीमा-आधारित परिशोधन को भीतर तक फैलने से रोकें
gmsh.option.setNumber('Mesh.MeshSizeExtendFromBoundary', 0)
gmsh.model.mesh.generate(3)
if "-nopopup" not in sys.argv:
    gmsh.fltk.run()
gmsh.finalize()यह क्यों मायने रखता है
स्थानीय परिशोधन की रणनीतियाँ अक्सर कई साइजिंग फ़ील्ड्स को एक साथ रखती हैं और उम्मीद करती हैं कि Min उन्हें स्वतंत्र रखेगा। जब सीमा-चालित विस्तार चालू होता है, तो ये उम्मीदें टूट सकती हैं—नतीजतन अनावश्यक तत्व बढ़ जाते हैं और मेशिंग या सॉल्वर का रनटाइम लंबा हो जाता है। सिर्फ एक विकल्प टॉगल करने से स्थानीयता वापस आ जाती है; साइज फ़ील्ड्स को दोबारा डिज़ाइन करने की जरूरत नहीं पड़ती।
निष्कर्ष
यदि डोमेन की सीमाओं के साथ लगाई गई चयनात्मक स्ट्राइप्स अचानक पूरे मॉडल में घना मेश बना दें, तो Mesh.MeshSizeExtendFromBoundary जांचें। इसे बंद करने से सीमा से भीतर तक होने वाला प्रसार रुक जाता है जो अन्य साइजिंग नियंत्रणों में दखल देता है। इस सेटअप में केवल Thickness बदलने से समस्या हल नहीं होती, जबकि विस्तार को बंद करने से होती है। Box फ़ील्ड्स और Min का संयोजन बनाए रखें—बस इतना सुनिश्चित करें कि यह विकल्प आपके परिशोधन की इच्छित स्थानीयता के अनुरूप हो।
यह लेख StackOverflow पर प्रश्न (लेखक: Nathaniel Wood) और Nathaniel Wood के उत्तर पर आधारित है।