Hi Hossam, Controlling the mesh density with the options "Mesh.CharacteristicLengthMin" and "Mesh.CharacteristicLengthMax" may be too stringent. It may be better to use the "mesh size field" feature if you want to impose a mesh density. Also, (I'm not sure about that) the last fragment operation with "Delete" specified might mess up the physical group.
I convert your .geo file to a python script in order to test your code via the gmsh python API. You can find attached this .py file. What you are trying to do seems somehow similar to what I do with gmsh and FEniCS (periodic homogenization for linear elasticity). You could be interested by some features of the python package HO-homog that we develop ( https://gitlab.enpc.fr/baptiste.durand/HO_homog ). Regards, Baptiste Durand ––––– Baptiste Durand Doctorant – Laboratoire Navier baptiste.dur...@enpc.fr – 01 64 15 37 21 ( 06 58 88 05 41 ) – linkedin.com/in/ bd1747 Today's Topics: 1. Composite RVE (Hossam Ragheb) ---------------------------------------------------------------------- Message: 1 Date: Thu, 10 Dec 2020 13:34:34 +0000 From: Hossam Ragheb <har1...@soton.ac.uk> To: gmsh@onelab.info Subject: [Gmsh] Composite RVE Message-ID: <8b4e55e8-f24a-5e9e-b0da-b21288631...@soton.ac.uk> Content-Type: text/plain; charset="utf-8"; Format="flowed" Hi, I am new to gmsh, so apologies if the answer to my question is obvious. I coded a .geo file (Attached) to create 3D RVE with fibers in a matrix that includes voids. The process simply is : ??? 1- Create box of the matrix material. ??? 2- Create voids using Sphere command and BooleanDifference to remove these from the matrix material. ??? 3- Create fibers as Cylinders and and utilise BooleanFragments to include the cylinders in the matrix. I have one persistent problem, once the mesh is created the fibers are meshed as hollow cylinders, however i need them to be solid. Its interesting behavior. Last thing to note that mesh size affects the outcome, for example when the min/max mesh size is 2, the result is solid cylinders, but with mesh size of 1, it becomes hollow. It there a way to force the meshing algorithm to mesh the cylinder as solid object? I have attached the .geo file, please let me know if you can help. Any suggestions? Thanks, Hossam Ragheb -------------- next part -------------- //------------------------------------------------------------------------------ // // Gmsh Stochastic Composite RVE // // Constructive Solid Geometry, OpenCASCADE geometry kernel // //------------------------------------------------------------------------------ SetFactory("OpenCASCADE"); Mesh.Tetrahedra = 1; Mesh.Triangles = 1; fac = 1; Mesh.CharacteristicLengthMin = 2*fac; Mesh.CharacteristicLengthMax = 2*fac; voiden = 0.01; Vf = 0.7; // Coefficent of variation of the fibre diameter cvf = 0.17; Vlratio = 20; Cube = 75*fac; frmean = 5.0 * fac; frmin = frmean - (frmean*cvf); frmax = frmean + (frmean*cvf); vrmin = 2.5*fac; vrmax = 5.0*fac; R = Cube; nSvoid = Floor((voiden*2*R*2*R*2*R)/((4/3)*3.1415926*vrmax*vrmax*vrmax)); nFibre = Floor((Vf*2*R*2*R*2*R)/(3.1415926*frmax*frmax*2*R)); dims = Floor(Sqrt(nFibre)); Box(1) = {-R,-R,-R, 2*R,2*R,2*R}; For s In {2:nSvoid} If (s < nSvoid) r = vrmin +Rand(vrmax-vrmin); x = -R + Rand(2*R); y = -R + Rand(2*R); z = -R + Rand(2*R); Sphere(s) = {x, y, z, r}; EndIf If (s == nSvoid) r = vrmin +Rand(vrmax-vrmin); x = -R + Rand(2*R); y = -R + Rand(2*R); z = -R + Rand(2*R); Sphere(s) = {x, y, z, r}; Dilate {{x, y, z}, {Vlratio, 1, 0.5}} { Volume{s}; } EndIf Physical Volume(s) = {s}; EndFor BooleanDifference(nSvoid+1) = { Volume{1}; Delete; }{ Volume{2:nSvoid}; Delete; }; dx = (2*R)/dims; count = 0; For i In {0:dims-1} For j In {0:dims-1} // Fibre diameter Fr = frmin +Rand(frmax-frmin); // Center of grid box in the RVE cgx = (-R + 0.5*dx) + j * dx; cgy = (-R + 0.5*dx) + i * dx; // Center of cylinder base xF = (cgx - 0.5*dx + Fr) + Rand(dx-2*Fr); yF = (cgy - 0.5*dx + Fr) + Rand(dx-2*Fr); zF = -R; // Cylinder axis dx,dy,dz dxF = 0; dyF = 0; dzF = 2*R; Cylinder(nSvoid+2+count) = {xF,yF,zF,dxF,dyF,dzF,Fr}; Physical Volume(nSvoid+2+count) = {nSvoid+2+count}; count = count +1; EndFor EndFor BooleanDifference(1000) = {Volume{nSvoid+1};Delete;}{Volume{nSvoid+2:nSvoid+1+count};}; Physical Volume("Matrix") = {1000}; Physical Volume("Fibres") = {nSvoid+2:nSvoid+1+count}; f() = BooleanFragments{Volume{1000};Delete;}{Volume{nSvoid+2:nSvoid+1+count};Delete;}; ------------------------------
import gmsh import math import random from subprocess import run gmsh.initialize() factory = gmsh.model.occ gmsh.option.setNumber("Mesh.Tetrahedra", 1) gmsh.option.setNumber("Mesh.Triangles", 1) gmsh.option.setNumber("General.Terminal", 1) gmsh.option.setNumber("General.Verbosity", 5) gmsh.option.setNumber("Mesh.SaveAll", 0) gmsh.option.setNumber("Mesh.MshFileVersion", 4.1) fac = 1 gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 2 * fac) gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 2 * fac) # geometry parameters voiden = 0.01 Vf = 0.7 # Coefficent of variation of the fibre diameter cvf = 0.17 Vlratio = 20 Cube = 75 * fac frmean = 5.0 * fac frmin = frmean - (frmean * cvf) frmax = frmean + (frmean * cvf) vrmin = 2.5 * fac vrmax = 5.0 * fac R = Cube nSvoid = math.floor( (voiden * 2 * R * 2 * R * 2 * R) / ((4 / 3) * math.pi * vrmax * vrmax * vrmax) ) nFibre = math.floor((Vf * 2 * R * 2 * R * 2 * R) / (math.pi * frmax * frmax * 2 * R)) dims = math.floor(math.sqrt(nFibre)) box_1 = factory.addBox(-R, -R, -R, 2 * R, 2 * R, 2 * R) spheres = list() for s in range(2, nSvoid + 1): if s < nSvoid: r = vrmin + random.uniform(0.0, vrmax - vrmin) x = -R + random.uniform(0.0, 2 * R) y = -R + random.uniform(0.0, 2 * R) z = -R + random.uniform(0.0, 2 * R) sphere = factory.addSphere(x, y, z, r) spheres.append(sphere) elif s == nSvoid: r = vrmin + random.uniform(0.0, vrmax - vrmin) x = -R + random.uniform(0.0, 2 * R) y = -R + random.uniform(0.0, 2 * R) z = -R + random.uniform(0.0, 2 * R) sphere = factory.addSphere(x, y, z, r) factory.dilate([(3, sphere)], x, y, z, Vlratio, 1, 0.5) spheres.append(sphere) phy_gp = gmsh.model.addPhysicalGroup(3, [sphere]) difference = factory.cut( [(3, box_1)], [(3, tag) for tag in spheres], removeObject=True, removeTool=True ) # get the tag : difference = difference[0][0][1] dx = (2 * R) / dims count = 0 # parameters for cylinder axis dxF, dyF, dzF = 0, 0, 2 * R cylinders = list() for i in range(0, dims): for j in range(0, dims): # Fibre diameter Fr = random.uniform(frmin, frmax) # Center of grid box in the RVE cgx = (-R + 0.5 * dx) + j * dx cgy = (-R + 0.5 * dx) + i * dx # Center of cylinder base xF = (cgx - 0.5 * dx + Fr) + random.uniform(0.0, dx - 2 * Fr) yF = (cgy - 0.5 * dx + Fr) + random.uniform(0.0, dx - 2 * Fr) zF = -R cylinder = factory.addCylinder(xF, yF, zF, dxF, dyF, dzF, Fr) cylinders.append(cylinder) phy_cylinders = list() for cyl in cylinders: phy_cyl = gmsh.model.addPhysicalGroup(3, [cyl]) phy_cylinders.append(phy_cyl) matrix = factory.cut( [(3, difference)], [(3, t) for t in cylinders], removeObject=True, removeTool=False ) matrix = matrix[0][0][1] phy_matrix = gmsh.model.addPhysicalGroup(3, [matrix]) gmsh.model.setPhysicalName(3, phy_matrix, "Matrix") phy_fibres = gmsh.model.addPhysicalGroup(3, cylinders) gmsh.model.setPhysicalName(3, phy_fibres, "Fibres") all_entities = gmsh.model.getEntities(3) # remove the matrix and the fibres : remove_entities = [e for e in all_entities if e[1] not in cylinders + [matrix]] gmsh.model.removeEntities(remove_entities, recursive=True) # factory.fragment([(3, matrix)], [(3, t) for t in cylinders]) factory.synchronize() gmsh.model.mesh.generate(3) gmsh.model.mesh.removeDuplicateNodes() gmsh.model.mesh.renumberNodes() gmsh.model.mesh.renumberElements() gmsh.write("rve.msh") try: run(f"meshio-convert rve.msh rve.xdmf", shell=True, check=True) except: pass gmsh.fltk.run()
_______________________________________________ gmsh mailing list gmsh@onelab.info http://onelab.info/mailman/listinfo/gmsh