From 6907542aa63a2518d538791bbc97e9451585af51 Mon Sep 17 00:00:00 2001 From: arswalid Date: Tue, 16 Apr 2024 10:34:55 -0600 Subject: [PATCH 1/5] meshing in py-gmsh --- mesh_generator.py | 445 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 444 insertions(+), 1 deletion(-) diff --git a/mesh_generator.py b/mesh_generator.py index 0e2fd10..82bfb8a 100644 --- a/mesh_generator.py +++ b/mesh_generator.py @@ -6,6 +6,27 @@ """ code to generate PV panel geometry and mesh """ +def _add_to_domain_markers(marker_name, gmsh_tags, entity_type): + # Create a dictionary to hold the gmsh tags associated with + # x_min, x_max, y_min, y_max, z_min, z_max panel surfaces and domain walls + + # if not hasattr(self, "domain_markers"): + # self.domain_markers = {} + # # Must start indexing at 1, if starting at 0, things marked "0" + # # are indistinguishable from things which receive no marking (and have default value of 0) + # self.domain_markers["_current_idx"] = 1 + + assert isinstance(gmsh_tags, list) + assert entity_type in ["cell", "facet"] + + marker_dict = { + "idx": domain_markers["_current_idx"], + "gmsh_tags": gmsh_tags, + "entity": entity_type, + } + + domain_markers[marker_name] = marker_dict + domain_markers["_current_idx"] += 1 ################################## @@ -51,6 +72,12 @@ surface_extended = 0.5 # a surface is created to cut the frame, the surface is created bigger than panel. +ndim = 3 +domain_markers = {} + # Must start indexing at 1, if starting at 0, things marked "0" + # are indistinguishable from things which receive no marking (and have default value of 0) +domain_markers["_current_idx"] = 1 +count_surface = 0 ######################################### # create panel geometry ######################################### @@ -82,6 +109,8 @@ left_frame_tag = left_frame[1][1] + + # create the front frame frame_surface_yz = gmsh.model.occ.copy([(2,frame_surface_xz)]) @@ -210,6 +239,164 @@ gmsh.model.occ.fragment([(3, final_front_frame_tag),(3, final_rear_frame_tag)],[(3, final_left_frame_tag), (3, final_right_frame_tag)]) +# 4 +# =============== +# | | +# | | +# y 1 | | 3 +# | | +# =============== +# 2 +# x +# +# gmsh.model.occ.synchronize() +count_volumes=0 +count_surface = 0 + +# # capture surfaces +# surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) +# for surf_tag in surf_tag_list: +# surf_id = surf_tag[1] +# com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) + +# # print(com) + +# _add_to_domain_markers(str(count_surface), [surf_id], "facet") +# count_surface +=1 +# print(count_surface) + +# # capture volumes +# frame_names = ["frm_left", "frm_bottom", "frm_right", "frm_top"] +# count_volumes=0 + +# vol_tag_list = gmsh.model.occ.getEntities(ndim) +# structure_vol_list = [] +# for vol_tag in vol_tag_list: +# vol_id = vol_tag[1] +# structure_vol_list.append(vol_id) +# _add_to_domain_markers(frame_names[count_volumes], [vol_id], "cell") +# count_volumes +=1 + +# # set physical attributes +# for key, data in domain_markers.items(): +# if isinstance(data, dict) and "gmsh_tags" in data: +# # print(key) +# # Cells (i.e., entities of dim = msh.topology.dim) +# if data["entity"] == "cell": +# gmsh.model.addPhysicalGroup( +# ndim, data["gmsh_tags"], data["idx"] +# ) +# gmsh.model.setPhysicalName(ndim, data["idx"], key) + +# # Facets (i.e., entities of dim = msh.topology.dim - 1) +# if data["entity"] == "facet": +# gmsh.model.addPhysicalGroup( +# ndim - 1, data["gmsh_tags"], data["idx"] +# ) +# gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) + + +min_dist=[] + + +# distance = gmsh.model.mesh.field.add("Distance") +# gmsh.model.mesh.field.setNumbers( +# distance, "FacesList", domain_markers["5"]["gmsh_tags"] +# ) + +# threshold = gmsh.model.mesh.field.add("Threshold") +# gmsh.model.mesh.field.setNumber(threshold, "IField", distance) + +# resolution = 0.17/100 +# # half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) +# # gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) +# # resolution = factor * 10 * params.pv_array.panel_thickness / 2 +# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) + +# gmsh.model.mesh.field.setNumber(threshold, "LcMax", 10 * resolution) +# gmsh.model.mesh.field.setNumber( +# threshold, "DistMin", resolution +# ) +# gmsh.model.mesh.field.setNumber( +# threshold, "DistMax", 3*resolution +# ) + + + + +def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): + distance = gmsh.model.mesh.field.add("Distance") + gmsh.model.mesh.field.setNumbers( + distance, "FacesList", domain_markers[surface_id]["gmsh_tags"] + ) + + threshold = gmsh.model.mesh.field.add("Threshold") + gmsh.model.mesh.field.setNumber(threshold, "IField", distance) + + + # half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) + # gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) + # resolution = factor * 10 * params.pv_array.panel_thickness / 2 + gmsh.model.mesh.field.setNumber(threshold, "LcMin", lcmin ) + + gmsh.model.mesh.field.setNumber(threshold, "LcMax", lcmax) + gmsh.model.mesh.field.setNumber( + threshold, "DistMin", dismin + ) + gmsh.model.mesh.field.setNumber( + threshold, "DistMax", distmax + ) + + return threshold + + +# for i in [1,2]: + + +# # resolution = 0.17/10 +# # threshold = set_length_scale(str(0 + (i-1)*18), resolution, 10*resolution, resolution, 3*resolution ) +# # min_dist.append(threshold) +# # threshold = set_length_scale(str(2+ (i-1)*18), resolution, 10*resolution, resolution, 3*resolution ) +# # min_dist.append(threshold) + + +# resolution = 0.17/100 +# for ids in [1,3]: +# threshold = set_length_scale(str(ids+ (i-1)*18), resolution, 2*resolution, resolution, 1.5*resolution )#3 +# min_dist.append(threshold) + +# for ids in [5]: +# threshold = set_length_scale(str(ids+ (i-1)*18), resolution, 2*resolution, resolution, 1.5*resolution )#10 +# min_dist.append(threshold) + + + +# resolution = 0.17/10 +# for ids in [0,18,36,52]: +# threshold = set_length_scale(str(ids), resolution, 10*resolution, resolution, 3*resolution ) +# min_dist.append(threshold) + +# minimum = gmsh.model.mesh.field.add("Min") +# gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", min_dist) +# gmsh.model.mesh.field.setAsBackgroundMesh(minimum) + +# gmsh.option.setNumber("Mesh.Algorithm", 6) +# gmsh.option.setNumber("Mesh.Algorithm3D", 1) +# gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 0) + + +# gmsh.model.mesh.generate(3) +# gmsh.model.mesh.setOrder(1) +# gmsh.model.mesh.optimize("Relocate3D") +# gmsh.model.mesh.refine +# # gmsh.model.mesh.generate(3) + + + + +# gmsh.write("panel_geo.msh") +# gmsh.write("panel_geo.vtk") + ########################### # create the panel ########################### @@ -248,6 +435,56 @@ gmsh.model.occ.fragment(cell_eva_frag[0], [(3,back_encap)], removeTool=True) # remove repeated interfaces, all index of involved volumes are not changed gmsh.model.occ.fragment([(3,back_encap)], [(3,back_sheet)], removeTool=True) # index of each layer are not changed. +# gmsh.model.occ.synchronize() + +# # capture surfaces +# surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) +# for surf_tag in surf_tag_list[count_surface:-1][:]: +# surf_id = surf_tag[1] +# com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) + +# # print(com) + +# _add_to_domain_markers("sur"+str(surf_id), [surf_id], "facet") +# count_surface +=1 +# print(count_surface) + +# # capture volumes +# # frame_names = ["frm_left", "frm_bottom", "frm_right", "frm_top"] +# # count_volumes=0 + +# vol_tag_list = gmsh.model.occ.getEntities(ndim) +# structure_vol_list = [] +# for vol_tag in vol_tag_list[count_volumes:-1][:]: +# vol_id = vol_tag[1] +# structure_vol_list.append(vol_id) +# _add_to_domain_markers("vol"+str(count_volumes), [vol_id], "cell") +# count_volumes +=1 + +# # set physical attributes +# for key, data in domain_markers.items(): +# if isinstance(data, dict) and "gmsh_tags" in data: +# # print(key) +# # Cells (i.e., entities of dim = msh.topology.dim) +# if data["entity"] == "cell": +# gmsh.model.addPhysicalGroup( +# ndim, data["gmsh_tags"], data["idx"] +# ) +# gmsh.model.setPhysicalName(ndim, data["idx"], key) +# print("added volume ", key) + +# # Facets (i.e., entities of dim = msh.topology.dim - 1) +# if data["entity"] == "facet": +# gmsh.model.addPhysicalGroup( +# ndim - 1, data["gmsh_tags"], data["idx"] +# ) +# gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) + +# gmsh.model.mesh.generate(3) +# gmsh.write("panel_geo.msh") +# gmsh.write("panel_geo.vtk") + + ######################################### # create seal layer geometry ######################################### @@ -268,6 +505,55 @@ gmsh.model.occ.synchronize() + +# capture surfaces +surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) +for surf_tag in surf_tag_list[count_surface:-1][:]: + surf_id = surf_tag[1] + com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) + + # print(com) + + _add_to_domain_markers("sur"+str(surf_id), [surf_id], "facet") + count_surface +=1 +print(count_surface) + +# capture volumes +# frame_names = ["frm_left", "frm_bottom", "frm_right", "frm_top"] +# count_volumes=0 + +vol_tag_list = gmsh.model.occ.getEntities(ndim) +structure_vol_list = [] +for vol_tag in vol_tag_list: + vol_id = vol_tag[1] + structure_vol_list.append(vol_id) + _add_to_domain_markers("vol"+str(count_volumes), [vol_id], "cell") + print(count_volumes) + count_volumes +=1 + +# set physical attributes +for key, data in domain_markers.items(): + if isinstance(data, dict) and "gmsh_tags" in data: + # print(key) + # Cells (i.e., entities of dim = msh.topology.dim) + if data["entity"] == "cell": + gmsh.model.addPhysicalGroup( + ndim, data["gmsh_tags"], data["idx"] + ) + gmsh.model.setPhysicalName(ndim, data["idx"], key) + print("added volume ", key) + + # Facets (i.e., entities of dim = msh.topology.dim - 1) + if data["entity"] == "facet": + gmsh.model.addPhysicalGroup( + ndim - 1, data["gmsh_tags"], data["idx"] + ) + gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) + +gmsh.model.mesh.generate(3) +gmsh.write("panel_geo.msh") +gmsh.write("panel_geo.vtk") + # ################################ # create physical groups # ################################ @@ -288,11 +574,168 @@ -gmsh.write("panel_geo.brep") +# gmsh.write("panel_geo.msh") + + +# tag surfaces + + + +# xmin = 0 +# xmax = +# ymin = 0 +# ymax = 0.39 +# zmin = +# zmax = + + + +surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) +for surf_tag in surf_tag_list: + surf_id = surf_tag[1] + com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) + + print(com) + + _add_to_domain_markers(str(count_surface), [surf_id], "facet") + count_surface +=1 + # sturctures tagging + # if np.isclose(com[0], params.domain.x_min): + # _add_to_domain_markers("x_min", [surf_id], "facet") + + # elif np.allclose(com[0], params.domain.x_max): + # _add_to_domain_markers("x_max", [surf_id], "facet") + + # elif np.allclose(com[1], params.domain.y_min): + # _add_to_domain_markers("y_min", [surf_id], "facet") + + # elif np.allclose(com[1], params.domain.y_max): + # _add_to_domain_markers("y_max", [surf_id], "facet") + + # elif np.allclose(com[2], params.domain.z_min): + # _add_to_domain_markers("z_min", [surf_id], "facet") + + # elif np.allclose(com[2], params.domain.z_max): + # _add_to_domain_markers("z_max", [surf_id], "facet") + +# set length scale +print(count_surface) + +vol_tag_list = gmsh.model.occ.getEntities(ndim) +structure_vol_list = [] +for vol_tag in vol_tag_list: + vol_id = vol_tag[1] + structure_vol_list.append(vol_id) + +_add_to_domain_markers("structure", structure_vol_list, "cell") + +for key, data in domain_markers.items(): + if isinstance(data, dict) and "gmsh_tags" in data: + # print(key) + # Cells (i.e., entities of dim = msh.topology.dim) + if data["entity"] == "cell": + gmsh.model.addPhysicalGroup( + ndim, data["gmsh_tags"], data["idx"] + ) + gmsh.model.setPhysicalName(ndim, data["idx"], key) + + # Facets (i.e., entities of dim = msh.topology.dim - 1) + if data["entity"] == "facet": + gmsh.model.addPhysicalGroup( + ndim - 1, data["gmsh_tags"], data["idx"] + ) + gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) + + + +min_dist = [] +# Define a distance field from the immersed panels +distance = gmsh.model.mesh.field.add("Distance") +gmsh.model.mesh.field.setNumbers( + distance, "FacesList", domain_markers["36"]["gmsh_tags"] +) +threshold = gmsh.model.mesh.field.add("Threshold") +gmsh.model.mesh.field.setNumber(threshold, "IField", distance) +resolution = 0.17/1000 +# half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) +# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) +# resolution = factor * 10 * params.pv_array.panel_thickness / 2 +gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) +gmsh.model.mesh.field.setNumber(threshold, "LcMax", 2 * resolution) +gmsh.model.mesh.field.setNumber( + threshold, "DistMin", 1 +) +gmsh.model.mesh.field.setNumber( + threshold, "DistMax", 3 +) +distance2 = gmsh.model.mesh.field.add("Distance") +gmsh.model.mesh.field.setNumbers( + distance2, "FacesList", domain_markers["83"]["gmsh_tags"] +) +threshold2 = gmsh.model.mesh.field.add("Threshold") +gmsh.model.mesh.field.setNumber(threshold, "IField", distance2) + +resolution = 1.5/1000 +# half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) +# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) +# resolution = factor * 10 * params.pv_array.panel_thickness / 2 +gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) + +gmsh.model.mesh.field.setNumber(threshold, "LcMax", 2 * resolution) +gmsh.model.mesh.field.setNumber( + threshold, "DistMin", 1 +) +gmsh.model.mesh.field.setNumber( + threshold, "DistMax", 3 +) + + +distance2 = gmsh.model.mesh.field.add("Distance") +gmsh.model.mesh.field.setNumbers( + distance2, + "FacesList", domain_markers["83"]["gmsh_tags"] +) +threshold2 = gmsh.model.mesh.field.add("Threshold") +gmsh.model.mesh.field.setNumber(threshold, "IField", distance2) + +resolution = 1.5/1000 +# half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) +# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) +# resolution = factor * 10 * params.pv_array.panel_thickness / 2 +gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) + +gmsh.model.mesh.field.setNumber(threshold, "LcMax", 2 * resolution) +gmsh.model.mesh.field.setNumber( + threshold, "DistMin", 1 +) +gmsh.model.mesh.field.setNumber( + threshold, "DistMax", 3 +) + +min_dist.append(threshold) +minimum = gmsh.model.mesh.field.add("Min") +gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", min_dist) +gmsh.model.mesh.field.setAsBackgroundMesh(minimum) + + + +# mesh generation + +gmsh.option.setNumber("Mesh.Algorithm", 6) +gmsh.option.setNumber("Mesh.Algorithm3D", 1) +gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 0) + +gmsh.model.mesh.generate(3) +gmsh.model.mesh.setOrder(2) +gmsh.model.mesh.optimize("Relocate3D") +gmsh.model.mesh.generate(3) + +gmsh.write("panel_geo.msh") +gmsh.write("panel_geo.vtk") # ####################### # # create mesh # ####################### From 338773399bbde9c5a6ab90579316d0b5dc9013e9 Mon Sep 17 00:00:00 2001 From: arswalid Date: Tue, 16 Apr 2024 15:17:33 -0600 Subject: [PATCH 2/5] meshing changes --- mesh_generator.py | 505 ++++++++++------------------------------------ 1 file changed, 112 insertions(+), 393 deletions(-) diff --git a/mesh_generator.py b/mesh_generator.py index 82bfb8a..2464339 100644 --- a/mesh_generator.py +++ b/mesh_generator.py @@ -28,6 +28,71 @@ def _add_to_domain_markers(marker_name, gmsh_tags, entity_type): domain_markers[marker_name] = marker_dict domain_markers["_current_idx"] += 1 +def from_domain_markers_to_PhysicalName(domain_markers,ndim): + # set physical attributes + for key, data in domain_markers.items(): + if isinstance(data, dict) and "gmsh_tags" in data: + # print(key) + # Cells (i.e., entities of dim = msh.topology.dim) + if data["entity"] == "cell": + gmsh.model.addPhysicalGroup( + ndim, data["gmsh_tags"], data["idx"] + ) + gmsh.model.setPhysicalName(ndim, data["idx"], key) + print("added volume ", key) + + # Facets (i.e., entities of dim = msh.topology.dim - 1) + if data["entity"] == "facet": + gmsh.model.addPhysicalGroup( + ndim - 1, data["gmsh_tags"], data["idx"] + ) + gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) + +def volume_tags(vol_list,count_volumes,structure_vol_list): + for vol_tag in vol_list: + vol_id = vol_tag[1] + # structure_vol_list.append("vol"+str(count_volumes)) + # _add_to_domain_markers("vol"+str(count_volumes), [vol_id], "cell") + _add_to_domain_markers(structure_vol_list[count_volumes], [vol_id], "cell") + # print(count_volumes) + count_volumes+=1 + return count_volumes, structure_vol_list + +def surface_tags(surf_list,count_surface,ndim): + for surf_tag in surf_list: + surf_id = surf_tag[1] + com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) + + # print(com) + + _add_to_domain_markers("sur"+str(surf_id), [surf_id], "facet") + count_surface +=1 + return count_surface + +def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): + distance = gmsh.model.mesh.field.add("Distance") + gmsh.model.mesh.field.setNumbers( + distance, "FacesList", domain_markers[surface_id]["gmsh_tags"] + ) + + threshold = gmsh.model.mesh.field.add("Threshold") + gmsh.model.mesh.field.setNumber(threshold, "IField", distance) + + + # half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) + # gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) + # resolution = factor * 10 * params.pv_array.panel_thickness / 2 + gmsh.model.mesh.field.setNumber(threshold, "LcMin", lcmin ) + + gmsh.model.mesh.field.setNumber(threshold, "LcMax", lcmax) + gmsh.model.mesh.field.setNumber( + threshold, "DistMin", dismin + ) + gmsh.model.mesh.field.setNumber( + threshold, "DistMax", distmax + ) + + return threshold ################################## # define parameters @@ -238,6 +303,8 @@ def _add_to_domain_markers(marker_name, gmsh_tags, entity_type): # remove interfaces between frames, all tags of frames are not changed gmsh.model.occ.fragment([(3, final_front_frame_tag),(3, final_rear_frame_tag)],[(3, final_left_frame_tag), (3, final_right_frame_tag)]) +gmsh.model.occ.synchronize() + # 4 # =============== @@ -255,145 +322,23 @@ def _add_to_domain_markers(marker_name, gmsh_tags, entity_type): # # capture surfaces # surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) -# for surf_tag in surf_tag_list: -# surf_id = surf_tag[1] -# com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) - -# # print(com) - -# _add_to_domain_markers(str(count_surface), [surf_id], "facet") -# count_surface +=1 -# print(count_surface) - -# # capture volumes -# frame_names = ["frm_left", "frm_bottom", "frm_right", "frm_top"] -# count_volumes=0 +# surf_list = surf_tag_list[count_surface:][:] +# count_surface = surface_tags(surf_list,count_surface,ndim) +structure_vol_list =["frm0","frm1","frm2","frm3"] # vol_tag_list = gmsh.model.occ.getEntities(ndim) -# structure_vol_list = [] -# for vol_tag in vol_tag_list: -# vol_id = vol_tag[1] -# structure_vol_list.append(vol_id) -# _add_to_domain_markers(frame_names[count_volumes], [vol_id], "cell") -# count_volumes +=1 - -# # set physical attributes -# for key, data in domain_markers.items(): -# if isinstance(data, dict) and "gmsh_tags" in data: -# # print(key) -# # Cells (i.e., entities of dim = msh.topology.dim) -# if data["entity"] == "cell": -# gmsh.model.addPhysicalGroup( -# ndim, data["gmsh_tags"], data["idx"] -# ) -# gmsh.model.setPhysicalName(ndim, data["idx"], key) - -# # Facets (i.e., entities of dim = msh.topology.dim - 1) -# if data["entity"] == "facet": -# gmsh.model.addPhysicalGroup( -# ndim - 1, data["gmsh_tags"], data["idx"] -# ) -# gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) - - -min_dist=[] - - -# distance = gmsh.model.mesh.field.add("Distance") -# gmsh.model.mesh.field.setNumbers( -# distance, "FacesList", domain_markers["5"]["gmsh_tags"] -# ) - -# threshold = gmsh.model.mesh.field.add("Threshold") -# gmsh.model.mesh.field.setNumber(threshold, "IField", distance) - -# resolution = 0.17/100 -# # half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) -# # gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) -# # resolution = factor * 10 * params.pv_array.panel_thickness / 2 -# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) - -# gmsh.model.mesh.field.setNumber(threshold, "LcMax", 10 * resolution) -# gmsh.model.mesh.field.setNumber( -# threshold, "DistMin", resolution -# ) -# gmsh.model.mesh.field.setNumber( -# threshold, "DistMax", 3*resolution -# ) - - - - -def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): - distance = gmsh.model.mesh.field.add("Distance") - gmsh.model.mesh.field.setNumbers( - distance, "FacesList", domain_markers[surface_id]["gmsh_tags"] - ) - - threshold = gmsh.model.mesh.field.add("Threshold") - gmsh.model.mesh.field.setNumber(threshold, "IField", distance) - - - # half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) - # gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) - # resolution = factor * 10 * params.pv_array.panel_thickness / 2 - gmsh.model.mesh.field.setNumber(threshold, "LcMin", lcmin ) - - gmsh.model.mesh.field.setNumber(threshold, "LcMax", lcmax) - gmsh.model.mesh.field.setNumber( - threshold, "DistMin", dismin - ) - gmsh.model.mesh.field.setNumber( - threshold, "DistMax", distmax - ) - - return threshold - - -# for i in [1,2]: - - -# # resolution = 0.17/10 -# # threshold = set_length_scale(str(0 + (i-1)*18), resolution, 10*resolution, resolution, 3*resolution ) -# # min_dist.append(threshold) -# # threshold = set_length_scale(str(2+ (i-1)*18), resolution, 10*resolution, resolution, 3*resolution ) -# # min_dist.append(threshold) +# vol_list = vol_tag_list[count_volumes:][:] +# count_volumes, structure_vol_list = volume_tags(vol_list,count_volumes,structure_vol_list) - -# resolution = 0.17/100 -# for ids in [1,3]: -# threshold = set_length_scale(str(ids+ (i-1)*18), resolution, 2*resolution, resolution, 1.5*resolution )#3 -# min_dist.append(threshold) - -# for ids in [5]: -# threshold = set_length_scale(str(ids+ (i-1)*18), resolution, 2*resolution, resolution, 1.5*resolution )#10 -# min_dist.append(threshold) - - - -# resolution = 0.17/10 -# for ids in [0,18,36,52]: -# threshold = set_length_scale(str(ids), resolution, 10*resolution, resolution, 3*resolution ) +# min_dist=[] +# for volid in structure_vol_list: +# threshold = set_length_scale(volid, frame_thick*100, frame_thick*100, 0, 0 )#3 # min_dist.append(threshold) -# minimum = gmsh.model.mesh.field.add("Min") -# gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", min_dist) -# gmsh.model.mesh.field.setAsBackgroundMesh(minimum) -# gmsh.option.setNumber("Mesh.Algorithm", 6) -# gmsh.option.setNumber("Mesh.Algorithm3D", 1) -# gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 0) - - -# gmsh.model.mesh.generate(3) -# gmsh.model.mesh.setOrder(1) -# gmsh.model.mesh.optimize("Relocate3D") -# gmsh.model.mesh.refine # # gmsh.model.mesh.generate(3) - - # gmsh.write("panel_geo.msh") # gmsh.write("panel_geo.vtk") @@ -435,55 +380,6 @@ def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): gmsh.model.occ.fragment(cell_eva_frag[0], [(3,back_encap)], removeTool=True) # remove repeated interfaces, all index of involved volumes are not changed gmsh.model.occ.fragment([(3,back_encap)], [(3,back_sheet)], removeTool=True) # index of each layer are not changed. -# gmsh.model.occ.synchronize() - -# # capture surfaces -# surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) -# for surf_tag in surf_tag_list[count_surface:-1][:]: -# surf_id = surf_tag[1] -# com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) - -# # print(com) - -# _add_to_domain_markers("sur"+str(surf_id), [surf_id], "facet") -# count_surface +=1 -# print(count_surface) - -# # capture volumes -# # frame_names = ["frm_left", "frm_bottom", "frm_right", "frm_top"] -# # count_volumes=0 - -# vol_tag_list = gmsh.model.occ.getEntities(ndim) -# structure_vol_list = [] -# for vol_tag in vol_tag_list[count_volumes:-1][:]: -# vol_id = vol_tag[1] -# structure_vol_list.append(vol_id) -# _add_to_domain_markers("vol"+str(count_volumes), [vol_id], "cell") -# count_volumes +=1 - -# # set physical attributes -# for key, data in domain_markers.items(): -# if isinstance(data, dict) and "gmsh_tags" in data: -# # print(key) -# # Cells (i.e., entities of dim = msh.topology.dim) -# if data["entity"] == "cell": -# gmsh.model.addPhysicalGroup( -# ndim, data["gmsh_tags"], data["idx"] -# ) -# gmsh.model.setPhysicalName(ndim, data["idx"], key) -# print("added volume ", key) - -# # Facets (i.e., entities of dim = msh.topology.dim - 1) -# if data["entity"] == "facet": -# gmsh.model.addPhysicalGroup( -# ndim - 1, data["gmsh_tags"], data["idx"] -# ) -# gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) - -# gmsh.model.mesh.generate(3) -# gmsh.write("panel_geo.msh") -# gmsh.write("panel_geo.vtk") - ######################################### # create seal layer geometry @@ -503,247 +399,70 @@ def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): gmsh.model.occ.fragment([(3, final_front_frame_tag),(3, final_rear_frame_tag),(3, final_left_frame_tag), (3, final_right_frame_tag)],[(3,seal)], removeTool=True) +# gmsh.model.occ.synchronize() gmsh.model.occ.synchronize() - -# capture surfaces +# # capture surfaces surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) -for surf_tag in surf_tag_list[count_surface:-1][:]: - surf_id = surf_tag[1] - com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) - - # print(com) - - _add_to_domain_markers("sur"+str(surf_id), [surf_id], "facet") - count_surface +=1 -print(count_surface) - -# capture volumes -# frame_names = ["frm_left", "frm_bottom", "frm_right", "frm_top"] -# count_volumes=0 +surf_list = surf_tag_list[count_surface:][:] +count_surface = surface_tags(surf_list,count_surface,ndim) vol_tag_list = gmsh.model.occ.getEntities(ndim) -structure_vol_list = [] -for vol_tag in vol_tag_list: - vol_id = vol_tag[1] - structure_vol_list.append(vol_id) - _add_to_domain_markers("vol"+str(count_volumes), [vol_id], "cell") - print(count_volumes) - count_volumes +=1 - -# set physical attributes -for key, data in domain_markers.items(): - if isinstance(data, dict) and "gmsh_tags" in data: - # print(key) - # Cells (i.e., entities of dim = msh.topology.dim) - if data["entity"] == "cell": - gmsh.model.addPhysicalGroup( - ndim, data["gmsh_tags"], data["idx"] - ) - gmsh.model.setPhysicalName(ndim, data["idx"], key) - print("added volume ", key) - - # Facets (i.e., entities of dim = msh.topology.dim - 1) - if data["entity"] == "facet": - gmsh.model.addPhysicalGroup( - ndim - 1, data["gmsh_tags"], data["idx"] - ) - gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) - -gmsh.model.mesh.generate(3) -gmsh.write("panel_geo.msh") -gmsh.write("panel_geo.vtk") - -# ################################ -# create physical groups -# ################################ -# # volume -gmsh.model.add_physical_group(3, [front_glass], 1) # front glass is marked as 1 -gmsh.model.add_physical_group(3, [front_encap], 2) # front encapsulant is marked as 2 -gmsh.model.add_physical_group(3, [cell_layer_encap_tag], 3) # encapsulant in cell layer (around the cells) is marked as 3 - -cell_tag_list = [] -for i in range(np.shape(cell_list)[0]): - cell_tag_list.append(cell_list[i][1]) -gmsh.model.add_physical_group(3, cell_tag_list, 4) # cells are marked as 4 - -gmsh.model.add_physical_group(3, [back_encap], 5) # back encapsulant is marked as 5 -gmsh.model.add_physical_group(3, [back_sheet], 6) # backsheet is marked as 6 -gmsh.model.add_physical_group(3, [seal], 7) # seal volume is marked as 7 -gmsh.model.add_physical_group(3, [final_front_frame_tag, final_rear_frame_tag, final_left_frame_tag, final_right_frame_tag], 8) # all frame is marked as 8 - - +vol_list = vol_tag_list[count_volumes:][:] +structure_vol_list +=["back_sheet","back_encap","front_encap","front_glass"] -# gmsh.write("panel_geo.msh") - - -# tag surfaces - - - -# xmin = 0 -# xmax = -# ymin = 0 -# ymax = 0.39 -# zmin = -# zmax = - - - -surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) -for surf_tag in surf_tag_list: - surf_id = surf_tag[1] - com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) - - print(com) - - _add_to_domain_markers(str(count_surface), [surf_id], "facet") - count_surface +=1 - # sturctures tagging - # if np.isclose(com[0], params.domain.x_min): - # _add_to_domain_markers("x_min", [surf_id], "facet") - - # elif np.allclose(com[0], params.domain.x_max): - # _add_to_domain_markers("x_max", [surf_id], "facet") - - # elif np.allclose(com[1], params.domain.y_min): - # _add_to_domain_markers("y_min", [surf_id], "facet") - - # elif np.allclose(com[1], params.domain.y_max): - # _add_to_domain_markers("y_max", [surf_id], "facet") - - # elif np.allclose(com[2], params.domain.z_min): - # _add_to_domain_markers("z_min", [surf_id], "facet") - - # elif np.allclose(com[2], params.domain.z_max): - # _add_to_domain_markers("z_max", [surf_id], "facet") - -# set length scale -print(count_surface) +for i in range(n_cell_length): + for j in range(n_cell_width): + structure_vol_list.append("cell"+str(i*n_cell_width + j)) -vol_tag_list = gmsh.model.occ.getEntities(ndim) -structure_vol_list = [] -for vol_tag in vol_tag_list: - vol_id = vol_tag[1] - structure_vol_list.append(vol_id) +structure_vol_list.append("cell_layer_encap") +structure_vol_list.append("seal") +count_volumes, structure_vol_list = volume_tags(vol_list,count_volumes,structure_vol_list) -_add_to_domain_markers("structure", structure_vol_list, "cell") +from_domain_markers_to_PhysicalName(domain_markers,ndim) -for key, data in domain_markers.items(): - if isinstance(data, dict) and "gmsh_tags" in data: - # print(key) - # Cells (i.e., entities of dim = msh.topology.dim) - if data["entity"] == "cell": - gmsh.model.addPhysicalGroup( - ndim, data["gmsh_tags"], data["idx"] - ) - gmsh.model.setPhysicalName(ndim, data["idx"], key) - # Facets (i.e., entities of dim = msh.topology.dim - 1) - if data["entity"] == "facet": - gmsh.model.addPhysicalGroup( - ndim - 1, data["gmsh_tags"], data["idx"] - ) - gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) +min_dist = [] +for volid in structure_vol_list: + threshold = set_length_scale(volid, frame_thick*1, frame_thick*10, 0, 0.1 )#3 + min_dist.append(threshold) +threshold = set_length_scale("back_sheet", back_sheet_thick*10 ,back_sheet_thick*100, 0, 0.1 )#3 +min_dist.append(threshold) +threshold = set_length_scale("back_encap", back_encap_thick*10 , back_encap_thick*100, 0, 0.1 )#3 +min_dist.append(threshold) +threshold = set_length_scale("front_encap", front_encap_thick*10 , front_encap_thick*100, 0, 0.1 )#3 +min_dist.append(threshold) +threshold = set_length_scale("front_glass", front_glass_thick*10, front_glass_thick*100, 0, 0.1 )#3 +min_dist.append(threshold) -min_dist = [] -# Define a distance field from the immersed panels -distance = gmsh.model.mesh.field.add("Distance") -gmsh.model.mesh.field.setNumbers( - distance, "FacesList", domain_markers["36"]["gmsh_tags"] -) - -threshold = gmsh.model.mesh.field.add("Threshold") -gmsh.model.mesh.field.setNumber(threshold, "IField", distance) - -resolution = 0.17/1000 -# half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) -# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) -# resolution = factor * 10 * params.pv_array.panel_thickness / 2 -gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) - -gmsh.model.mesh.field.setNumber(threshold, "LcMax", 2 * resolution) -gmsh.model.mesh.field.setNumber( - threshold, "DistMin", 1 -) -gmsh.model.mesh.field.setNumber( - threshold, "DistMax", 3 -) - -distance2 = gmsh.model.mesh.field.add("Distance") -gmsh.model.mesh.field.setNumbers( - distance2, "FacesList", domain_markers["83"]["gmsh_tags"] -) -threshold2 = gmsh.model.mesh.field.add("Threshold") -gmsh.model.mesh.field.setNumber(threshold, "IField", distance2) - -resolution = 1.5/1000 -# half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) -# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) -# resolution = factor * 10 * params.pv_array.panel_thickness / 2 -gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) - -gmsh.model.mesh.field.setNumber(threshold, "LcMax", 2 * resolution) -gmsh.model.mesh.field.setNumber( - threshold, "DistMin", 1 -) -gmsh.model.mesh.field.setNumber( - threshold, "DistMax", 3 -) - - -distance2 = gmsh.model.mesh.field.add("Distance") -gmsh.model.mesh.field.setNumbers( - distance2, - "FacesList", domain_markers["83"]["gmsh_tags"] -) -threshold2 = gmsh.model.mesh.field.add("Threshold") -gmsh.model.mesh.field.setNumber(threshold, "IField", distance2) - -resolution = 1.5/1000 -# half_panel = params.pv_array.panel_chord * np.cos(params.pv_array.tracker_angle) -# gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution * 0.5) -# resolution = factor * 10 * params.pv_array.panel_thickness / 2 -gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution ) - -gmsh.model.mesh.field.setNumber(threshold, "LcMax", 2 * resolution) -gmsh.model.mesh.field.setNumber( - threshold, "DistMin", 1 -) -gmsh.model.mesh.field.setNumber( - threshold, "DistMax", 3 -) +for i in range(n_cell_length): + for j in range(n_cell_width): + threshold = set_length_scale("cell"+str(i*n_cell_width + j), cell_thick*1, cell_thick*10, 0, .1 )#3 + min_dist.append(threshold) +threshold = set_length_scale("seal", seal_thick*10 , seal_thick*100, 0, 0.1 )#3 min_dist.append(threshold) + minimum = gmsh.model.mesh.field.add("Min") gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", min_dist) gmsh.model.mesh.field.setAsBackgroundMesh(minimum) +gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0) +gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0) +gmsh.option.setNumber("Mesh.MeshSizeFromCurvature", 0) -# mesh generation -gmsh.option.setNumber("Mesh.Algorithm", 6) +gmsh.option.setNumber("Mesh.Algorithm", 5) gmsh.option.setNumber("Mesh.Algorithm3D", 1) gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 0) +gmsh.model.mesh.setOrder(1) -gmsh.model.mesh.generate(3) -gmsh.model.mesh.setOrder(2) -gmsh.model.mesh.optimize("Relocate3D") -gmsh.model.mesh.generate(3) +gmsh.model.mesh.generate(3) gmsh.write("panel_geo.msh") gmsh.write("panel_geo.vtk") -# ####################### -# # create mesh -# ####################### - -# gmsh.option.setNumber('Mesh.MeshSizeMin', 0.001) -# gmsh.option.setNumber('Mesh.MeshSizeMax', 0.001) - -# gmsh.model.mesh.generate(3) -# gmsh.write('panel.vtk') gmsh.finalize() From 4f5ea74715230834f492a865616e0311acbd692e Mon Sep 17 00:00:00 2001 From: arswalid Date: Tue, 14 May 2024 10:57:02 -0600 Subject: [PATCH 3/5] First iteration for gui - addition of gui.py which opens a gui to input variables that will be used to generate a PV panel --- gui.py | 165 ++++++++++++++++++++++++++++++++++++++++++++++ input.txt | 6 ++ mesh_generator.py | 57 +++++++++++++++- original.txt | 6 ++ 4 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 gui.py create mode 100644 input.txt create mode 100644 original.txt diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..c734d6f --- /dev/null +++ b/gui.py @@ -0,0 +1,165 @@ +import tkinter as tk +from tkinter import filedialog +from tkinter import scrolledtext +import subprocess +import os +import tempfile + +def load_preset_values(preset_file_path): + # Initialize variables + preset_values = {} + + # Read preset values from the text file + with open(preset_file_path, 'r') as file: + lines = file.readlines() + for line in lines: + key, value = line.strip().split(": ") + preset_values[key] = value + + return preset_values + +def generate_text_and_execute_script(): + # Retrieve input values + cell_thick = cell_thick_entry.get() + n_cell_length = n_cell_length_entry.get() + n_cell_width = n_cell_width_entry.get() + front_glass_thick = var1_entry.get() + front_encap_thick = var2_entry.get() + back_encap_thick = var3_entry.get() + + # Get the directory of the current script + script_directory = os.path.dirname(os.path.abspath(__file__)) + + # Generate a random filename for the text file + random_filename = "input" #next(tempfile._get_candidate_names()) + text_file_path = os.path.join(script_directory, random_filename + ".txt") + + # Write input values to the text file + with open(text_file_path, 'w') as file: + file.write(f"cell_thick: {cell_thick}\n") + file.write(f"n_cell_length: {n_cell_length}\n") + file.write(f"n_cell_width: {n_cell_width}\n") + file.write(f"front_glass_thick: {front_glass_thick}\n") + file.write(f"front_encap_thick: {front_encap_thick}\n") + file.write(f"back_encap_thick: {back_encap_thick}\n") + + # Inform the user that the text file has been generated + result_label.config(text="Text file generated successfully!") + + # Execute the other Python script with the input values as arguments + script_path = "mesh_generator.py" + command = ["python", script_path, cell_thick, n_cell_length, n_cell_width, front_glass_thick, front_encap_thick, back_encap_thick] + + # Start the subprocess and capture its output + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + + # Display the output in the result text widget + output_text = "" + while True: + line = process.stdout.readline() + if line == '' and process.poll() is not None: + break + if line: + output_text += line.strip() + "\n" + output_text = output_text[-500:] # Limiting the output to 500 characters + output_text_widget.config(state=tk.NORMAL) + output_text_widget.delete(1.0, tk.END) # Clear previous output + output_text_widget.insert(tk.END, output_text) + output_text_widget.config(state=tk.DISABLED) # Prevent editing of output + output_text_widget.see(tk.END) # Scroll to the bottom + + # Wait for the subprocess to finish + process.wait() + + # Inform the user that the script has been executed + result_label.config(text=result_label.cget("text") + "\nScript executed successfully!") + +# Create GUI window +root = tk.Tk() +root.title("PV panels generator (PVmesh)") + +# Paragraph at the top +intro_text = """ +Welcome to the Text File Generator and Script Executor. +Please fill out the following information: +""" +intro_label = tk.Label(root, text=intro_text) +intro_label.grid(row=0, column=0, columnspan=2, padx=10, pady=10, sticky="w") + +# Load preset values from a different text file +preset_file_path = "original.txt" # Replace with the actual path of the preset file +preset_values = load_preset_values(preset_file_path) + +# Display preset values +preset_label_text = "Preset Values:" +preset_label = tk.Label(root, text=preset_label_text, font=("Arial", 10, "bold")) +preset_label.grid(row=1, column=0, padx=5, pady=5, sticky="w") + +# cell_thick input with preset value +cell_thick_label = tk.Label(root, text="cell_thick:") +cell_thick_label.grid(row=2, column=0, padx=5, pady=5, sticky="e") +cell_thick_entry = tk.Entry(root) +cell_thick_entry.insert(0, preset_values.get("cell_thick", "")) +cell_thick_entry.grid(row=2, column=1, padx=5, pady=5) + +# n_cell_length input with preset value +n_cell_length_label = tk.Label(root, text="n_cell_length:") +n_cell_length_label.grid(row=3, column=0, padx=5, pady=5, sticky="e") +n_cell_length_entry = tk.Entry(root) +n_cell_length_entry.insert(0, preset_values.get("n_cell_length", "")) +n_cell_length_entry.grid(row=3, column=1, padx=5, pady=5) + +# n_cell_width input with preset value +n_cell_width_label = tk.Label(root, text="n_cell_width:") +n_cell_width_label.grid(row=4, column=0, padx=5, pady=5, sticky="e") +n_cell_width_entry = tk.Entry(root) +n_cell_width_entry.insert(0, preset_values.get("n_cell_width", "")) +n_cell_width_entry.grid(row=4, column=1, padx=5, pady=5) + +# Additional front_glass_thick input with preset value +var1_label = tk.Label(root, text="front_glass_thick:") +var1_label.grid(row=5, column=0, padx=5, pady=5, sticky="e") +var1_entry = tk.Entry(root) +var1_entry.insert(0, preset_values.get("front_glass_thick", "")) +var1_entry.grid(row=5, column=1, padx=5, pady=5) + +# Additional front_encap_thick input with preset value +var2_label = tk.Label(root, text="front_encap_thick:") +var2_label.grid(row=6, column=0, padx=5, pady=5, sticky="e") +var2_entry = tk.Entry(root) +var2_entry.insert(0, preset_values.get("front_encap_thick", "")) +var2_entry.grid(row=6, column=1, padx=5, pady=5) + +# Additional back_encap_thick input with preset value +var3_label = tk.Label(root, text="back_encap_thick:") +var3_label.grid(row=7, column=0, padx=5, pady=5, sticky="e") +var3_entry = tk.Entry(root) +var3_entry.insert(0, preset_values.get("back_encap_thick", "")) +var3_entry.grid(row=7, column=1, padx=5, pady=5) + +# Load an image +img = tk.PhotoImage(file="panel.png") # Replace "image.png" with the path to your image + +# Display the image +img_label = tk.Label(root, image=img) +img_label.grid(row=2, column=2, rowspan=6, padx=10, pady=10, sticky="w") + +# Output text widget to display subprocess output +output_text_widget = scrolledtext.ScrolledText(root, width=40, height=10) +output_text_widget.grid(row=2, column=3, rowspan=6, padx=10, pady=10, sticky="w") + +# Footnote +footnote_text = "This is a footnote." +footnote_label = tk.Label(root, text=footnote_text, font=("Arial", 8), fg="gray") +footnote_label.grid(row=8, column=0, columnspan=2, padx=10, pady=5, sticky="w") + +# Button to generate text file and execute script +execute_button = tk.Button(root, text="Generate Text File and Execute Script", command=generate_text_and_execute_script) +execute_button.grid(row=9, columnspan=2, padx=5, pady=10) + +# Label to display result +result_label = tk.Label(root, text="") +result_label.grid(row=10, columnspan=2) + +# Start GUI main loop +root.mainloop() diff --git a/input.txt b/input.txt new file mode 100644 index 0000000..ba895fb --- /dev/null +++ b/input.txt @@ -0,0 +1,6 @@ +cell_thick: 0.17/1000 +n_cell_length: 3 +n_cell_width: 2 +front_glass_thick: 3.2/1000 +front_encap_thick: 0.45/1000 +back_encap_thick: 0.45/1000 diff --git a/mesh_generator.py b/mesh_generator.py index 2464339..9413ad6 100644 --- a/mesh_generator.py +++ b/mesh_generator.py @@ -94,10 +94,63 @@ def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): return threshold + +def process_input_file(input_file_path): + # Initialize variables + cell_thick = '' + n_cell_length = '' + n_cell_width = '' + front_glass_thick = '' + front_encap_thick= '' + back_encap_thick= '' + + # Read input values from the text file + try: + with open(input_file_path, 'r') as file: + lines = file.readlines() + except FileNotFoundError: + print(f"{input_file_path} not found. Reading from original.txt instead.") + input_file_path = "original.txt" + with open(input_file_path, 'r') as file: + lines = file.readlines() + + for line in lines: + key, value = line.strip().split(": ") + if key == "cell_thick": + cell_thick = value + elif key == "n_cell_length": + n_cell_length = value + elif key == "n_cell_width": + n_cell_width = value + elif key == "front_glass_thick": + front_glass_thick = value + elif key == "front_encap_thick": + front_encap_thick = value + elif key == "back_encap_thick": + back_encap_thick = value + + # Print the variables (replace with your processing logic) + print("cell_thick:", cell_thick) + print("n_cell_length:", n_cell_length) + print("n_cell_width:", n_cell_width) + print("front_glass_thick:", front_glass_thick) + print("front_encap_thick:", front_encap_thick) + print("back_encap_thick:", back_encap_thick) + + + +input_file_path = "input.txt" # Replace with the actual path of the input file +process_input_file(input_file_path) + + ################################## # define parameters ################################## + +exit() + + cell_length = 182.0/1000 # length of each cell in m cell_width = 182.0/1000 # width of each cell in m cell_thick = 0.17/1000 # thick ness of cell in m @@ -423,7 +476,7 @@ def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): min_dist = [] -for volid in structure_vol_list: +for volid in structure_vol_list[0:4]: threshold = set_length_scale(volid, frame_thick*1, frame_thick*10, 0, 0.1 )#3 min_dist.append(threshold) @@ -439,7 +492,7 @@ def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): for i in range(n_cell_length): for j in range(n_cell_width): - threshold = set_length_scale("cell"+str(i*n_cell_width + j), cell_thick*1, cell_thick*10, 0, .1 )#3 + threshold = set_length_scale("cell"+str(i*n_cell_width + j), cell_thick*.5, cell_thick*1, 0, .1 )#3 min_dist.append(threshold) threshold = set_length_scale("seal", seal_thick*10 , seal_thick*100, 0, 0.1 )#3 diff --git a/original.txt b/original.txt new file mode 100644 index 0000000..0819294 --- /dev/null +++ b/original.txt @@ -0,0 +1,6 @@ +cell_thick: 0.17/1000 +n_cell_length: 3 +n_cell_width: 2 +front_glass_thick: 3.2/1000 +front_encap_thick: 0.45/1000 +back_encap_thick: 0.45/1000 \ No newline at end of file From 66caf1084ab12c475f094d14864cac109cde12d3 Mon Sep 17 00:00:00 2001 From: arswalid Date: Tue, 21 May 2024 14:52:07 -0600 Subject: [PATCH 4/5] addition of the panel picture --- panel.png | Bin 0 -> 2413 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 panel.png diff --git a/panel.png b/panel.png new file mode 100644 index 0000000000000000000000000000000000000000..a554b980f72c2dca2c2f5564e32a4f8bb3f8c9fe GIT binary patch literal 2413 zcmd6pX*3&%7RRG=bQH0bQcFFtv>jUsreZ5%D@sdIOH`?SNr{ME+h{^9&8WSE#xfnW zVy_4zv9yocX)LjnS|*lQgOrT(KD>9{r}y=Jx&QzF+;i_a_xI_h*x#`L@=Edo005ws zCG;Kuz@>8Lb9m03RfaAo`AkF+W-bV0I6OGO+Y1p877DQU3iomfcpUZm+3WiNzy(n& zsIemown3+dIjqS1xsAW5mynXVK@+h0#K-j;^BzpcR;Fqq#L=xq+^xjl<0dyq5u@PU#xAFq?1;?waR;*I zZy(b#nv$oyNs)fOfscZ}GAyq4+J63^kZ;p=auRk!M3t)0FgEa1Rf4&1p;8bG^j2_v zZsp&;L)5t`#Ctw&U{kGm`rQ#ZUM}(Ic94=ARU&2Lp@`0AGVQ$S!mGJS`uF`7{o-OW zv61Q%Bq2{M&qMe8a)tK8(5{;nI@=1?)@Wkv>*NOm-O{^fQ70`or4xS~@|nL~%R>*| z*RS134~g+jIOu$fmDazZudU&9!j8QC?6xWYSz_ySDK@REhxS|=S5rU5uAIB<_q+2bc$?OU%)U@crG zL04G@g=j^$k26zQhq%wr$LF55ZlrZN^!DaBPkddxPKdhIWq1ZnVCChYl1R$fY3FIu z0cE9cD6I&$`h=8mXVXZ(Jrn1`M{@5E4ijg!qxPqOY5}fG!~gsXm$JZ0L>5m=nj-Vj zZn|sx?X~h^0+<@nO}v|ql}n1**GEeCuc)cu4WkeDlowgcPP76ipIjcZ zGMCpiA=~U?&#aswFY9faxmO+oXvO?sjjS5@O`D1l=MQum8)DN1J_!ugx?rv8cD9}J zIDoMYAV^M|xop6%f#T{K%27#o(>Fk(0+^8b1dU)gu$8N-)m`9t;)a4KohpY{Y2+W=>mJCmhwel_$PoKwfZAOy zmcT!E8<~*g#o#ehz~{QOQL;=IvdSkQ@!^`e(+w*VW1GUMn-}8*Fge>TbZ-LNtjzus zXMW~7;k!(?IcKRf!=>$}Xe46mG>TRnc}R$w-D6ELwtSV#NAtgD(>(=WiaXr8J+kT+jvw5x>B4eQ;nw;^I;!49+m z=TllqypY#@2*z}+y6+y}LB8TUgke6YjgGaqtAvfX)DNn7H3wjMfQWv@bZvIO2(mCz z&cypTS8HQNZh?B=9v+Csj z)yR6c=lMPkw!l|oj8azz1*axpYRpkZPk9Q<6Ro@<6ox+3|6Gx^q=OL5Pu?VA)qO-O z&2Lr57`=Rh0sjO>NP$d7wPxfXY|;i<$O7;R1DhE-l7*LiHGN4Tk(-#Ng`23fZUe{96iAnY+b;MjsD@ z2=@VdTKibaiFcR|UdNUDmYqWuyvm48HEIiM;7uxC2Jwd=!?d-nxyFRO5?6CiXDMzg znXeN_8arL2inR{zq*4gTJ>4^bO{tlV3e8CW|0}vGRae~j%5ZIN66|u>GA&(;pR4QbhMh>-2P@$ZJ?O5@-)*k(l-X`v$r;t zGT!a!&Y8aVCnpoyxjGF%4LsQ%c}&nI1)TOXj5zD$FnYWsoX($aF`ANRSD3+nst!RJ zY5MGi0@VGNLczE_cQ!pLA$E|xnOtuk#3k|jmQ9O1d6_ecAC#;)_prK?hbu4nKVbeF d)Bi~899$Xl$d5yQb@o32tjz8}- Date: Fri, 16 Aug 2024 11:23:49 -0600 Subject: [PATCH 5/5] Update mesh_generator.py --- mesh_generator.py | 652 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 486 insertions(+), 166 deletions(-) diff --git a/mesh_generator.py b/mesh_generator.py index 9413ad6..9398f04 100644 --- a/mesh_generator.py +++ b/mesh_generator.py @@ -7,27 +7,21 @@ code to generate PV panel geometry and mesh """ def _add_to_domain_markers(marker_name, gmsh_tags, entity_type): - # Create a dictionary to hold the gmsh tags associated with - # x_min, x_max, y_min, y_max, z_min, z_max panel surfaces and domain walls + # Create a dictionary to hold the gmsh tags associated with + # entity name and type - # if not hasattr(self, "domain_markers"): - # self.domain_markers = {} - # # Must start indexing at 1, if starting at 0, things marked "0" - # # are indistinguishable from things which receive no marking (and have default value of 0) - # self.domain_markers["_current_idx"] = 1 + assert isinstance(gmsh_tags, list) + assert entity_type in ["cell", "facet"] - assert isinstance(gmsh_tags, list) - assert entity_type in ["cell", "facet"] - - marker_dict = { - "idx": domain_markers["_current_idx"], - "gmsh_tags": gmsh_tags, - "entity": entity_type, - } - - domain_markers[marker_name] = marker_dict - domain_markers["_current_idx"] += 1 + marker_dict = { + "idx": domain_markers["_current_idx"], + "gmsh_tags": gmsh_tags, + "entity": entity_type, + } + domain_markers[marker_name] = marker_dict + domain_markers["_current_idx"] += 1 + def from_domain_markers_to_PhysicalName(domain_markers,ndim): # set physical attributes for key, data in domain_markers.items(): @@ -39,7 +33,6 @@ def from_domain_markers_to_PhysicalName(domain_markers,ndim): ndim, data["gmsh_tags"], data["idx"] ) gmsh.model.setPhysicalName(ndim, data["idx"], key) - print("added volume ", key) # Facets (i.e., entities of dim = msh.topology.dim - 1) if data["entity"] == "facet": @@ -48,23 +41,16 @@ def from_domain_markers_to_PhysicalName(domain_markers,ndim): ) gmsh.model.setPhysicalName(ndim - 1, data["idx"], key) -def volume_tags(vol_list,count_volumes,structure_vol_list): - for vol_tag in vol_list: - vol_id = vol_tag[1] - # structure_vol_list.append("vol"+str(count_volumes)) - # _add_to_domain_markers("vol"+str(count_volumes), [vol_id], "cell") - _add_to_domain_markers(structure_vol_list[count_volumes], [vol_id], "cell") - # print(count_volumes) +def volume_tags(vol_list,count_volumes,structure_vol_list, number_volume_groups): # number_volumes = number of cells + 4 (frames) +1(seal) + 5(glass, eva,eva,eva,backsheet) + for i in range(number_volume_groups): + _add_to_domain_markers(structure_vol_list[count_volumes], vol_list[count_volumes], "cell") count_volumes+=1 - return count_volumes, structure_vol_list + return count_volumes -def surface_tags(surf_list,count_surface,ndim): +def surface_tags(surf_list,count_surface): for surf_tag in surf_list: surf_id = surf_tag[1] - com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) - - # print(com) - + # com = gmsh.model.occ.getCenterOfMass(ndim - 1, surf_id) _add_to_domain_markers("sur"+str(surf_id), [surf_id], "facet") count_surface +=1 return count_surface @@ -72,7 +58,7 @@ def surface_tags(surf_list,count_surface,ndim): def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): distance = gmsh.model.mesh.field.add("Distance") gmsh.model.mesh.field.setNumbers( - distance, "FacesList", domain_markers[surface_id]["gmsh_tags"] + distance, "FacesList", domain_markers[surface_id]["gmsh_tags"] # field of distance to suface with tage "gmsh_tags" ) threshold = gmsh.model.mesh.field.add("Threshold") @@ -90,7 +76,8 @@ def set_length_scale(surface_id, lcmin, lcmax, dismin, distmax ): ) gmsh.model.mesh.field.setNumber( threshold, "DistMax", distmax - ) + ) # when distance to the surface > distmax, mesh size=lcmax, if when distance to the surface < distmin, mesh size=lcmin + # between distmax and istmin, mesh size is linearly interpolated between lcmin and lcmax return threshold @@ -130,33 +117,29 @@ def process_input_file(input_file_path): back_encap_thick = value # Print the variables (replace with your processing logic) - print("cell_thick:", cell_thick) - print("n_cell_length:", n_cell_length) - print("n_cell_width:", n_cell_width) - print("front_glass_thick:", front_glass_thick) - print("front_encap_thick:", front_encap_thick) - print("back_encap_thick:", back_encap_thick) - + # print("cell_thick:", cell_thick) + # print("n_cell_length:", n_cell_length) + # print("n_cell_width:", n_cell_width) + # print("front_glass_thick:", front_glass_thick) + # print("front_encap_thick:", front_encap_thick) + # print("back_encap_thick:", back_encap_thick) -input_file_path = "input.txt" # Replace with the actual path of the input file -process_input_file(input_file_path) - - -################################## -# define parameters -################################## +# input_file_path = "input.txt" # Replace with the actual path of the input file +# process_input_file(input_file_path) -exit() +""" +define parameters +""" -cell_length = 182.0/1000 # length of each cell in m +cell_length = 182.0/1000 # length of each cell in m cell_width = 182.0/1000 # width of each cell in m cell_thick = 0.17/1000 # thick ness of cell in m -n_cell_length = 3 # number of cells along x -n_cell_width = 2 # number of cells along y +n_cell_length = 12 # number of cells along x +n_cell_width = 6 # number of cells along y perimeter_margin = 10.0/1000 # edge margin in m @@ -164,15 +147,15 @@ def process_input_file(input_file_path): cell_cell_gap_y = 2.5/1000 # gap between cell along y, in m front_glass_thick = 3.2/1000 # thickness of gront glass layer -front_encap_thick = 0.45/1000 # thickness of front encapsulant layer, in m -back_encap_thick = 0.45/1000 # thickness of back encapsulant layer, in m +front_encap_thick = 0.45/1000-cell_thick/2 # thickness of front encapsulant layer, in m +back_encap_thick = 0.45/1000-cell_thick/2 # thickness of back encapsulant layer, in m back_sheet_thick = 0.35/1000 # thickness of backsheet or back glass, in m panel_thick = cell_thick+front_glass_thick+front_encap_thick+back_encap_thick+back_sheet_thick panel_length = cell_length*n_cell_length+(n_cell_length-1)*cell_cell_gap_x+2*perimeter_margin # total length of the panel panel_width = cell_width*n_cell_width+(n_cell_width-1)*cell_cell_gap_y+2*perimeter_margin # total width of the panel -clip_thick = 6.0/1000 # open space of frame (parameter d) +clip_thick = 6.0/1000 # open space of frame (parameter d, d-2e is panel thickness) seal_length = 2.0/1000 # width of seal (distance from panel edge to frame, parameter f) seal_thick = (clip_thick-panel_thick)/2 # distance from top of panel to fram (parameter e) @@ -186,29 +169,25 @@ def process_input_file(input_file_path): cover_length = c-frame_thick-seal_length # covered length of panel at each edge. -frame_extended = 0.1 # the frame is created longer than panel then the extended part is cutted off +frame_extended = 0.1*cell_length # the frame is created longer than panel then the extended part is cutted off surface_extended = 0.5 # a surface is created to cut the frame, the surface is created bigger than panel. ndim = 3 -domain_markers = {} - # Must start indexing at 1, if starting at 0, things marked "0" - # are indistinguishable from things which receive no marking (and have default value of 0) -domain_markers["_current_idx"] = 1 -count_surface = 0 -######################################### -# create panel geometry -######################################### + gmsh.initialize() gmsh.model.add("panel") -######################################### -# create frame geometry -######################################### +""" +create frame geometry +""" +######################### # create the left frame +######################### + whole_frame_surface_xy_plane = gmsh.model.occ.add_rectangle(-seal_length-frame_thick, seal_thick+frame_thick+panel_thick-h, 0, a,h) subtract_frame_surface_1_xy_plane = gmsh.model.occ.add_rectangle(2*frame_thick+b-seal_length-frame_thick, seal_thick+frame_thick+panel_thick-h+frame_thick, 0, a-2*frame_thick-b, h-3*frame_thick-2*seal_thick-panel_thick) subtract_frame_surface_2_xy_plane = gmsh.model.occ.add_rectangle(cover_length, -seal_thick-frame_thick, 0, a-c, 2*frame_thick+2*seal_thick+panel_thick) @@ -216,6 +195,7 @@ def process_input_file(input_file_path): subtract_frame_surface_4_xy_plane = gmsh.model.occ.add_rectangle(-seal_length, seal_thick+frame_thick+panel_thick-h+frame_thick, 0, b, h-3*frame_thick-2*seal_thick-panel_thick) frame_surface_xz = subtract_frame_surface_4_xy_plane+1 + gmsh.model.occ.cut([(2, whole_frame_surface_xy_plane)], [(2, subtract_frame_surface_1_xy_plane),(2, subtract_frame_surface_2_xy_plane),(2, subtract_frame_surface_3_xy_plane),(2, subtract_frame_surface_4_xy_plane)], tag = frame_surface_xz) gmsh.model.occ.rotate([(2,frame_surface_xz)], 0,0,0,1,0,0,math.pi/2) @@ -227,42 +207,48 @@ def process_input_file(input_file_path): left_frame_tag = left_frame[1][1] - - +######################### # create the front frame +######################### frame_surface_yz = gmsh.model.occ.copy([(2,frame_surface_xz)]) gmsh.model.occ.rotate(frame_surface_yz, 0,0,0,0,0,1,math.pi/2) -gmsh.model.occ.translate(frame_surface_yz,-seal_length-2*frame_extended,0,0) +gmsh.model.occ.translate(frame_surface_yz,-2*seal_length-2*frame_extended,0,0) front_frame = gmsh.model.occ.extrude(frame_surface_yz, panel_length+2*seal_length+2*frame_extended,0,0) front_frame_tag = front_frame[1][1] +######################### # create the right frame +######################### + frame_surface_right = gmsh.model.occ.copy(frame_surface_yz) -gmsh.model.occ.translate(frame_surface_right, frame_extended+panel_length+seal_length,0,0) +gmsh.model.occ.translate(frame_surface_right, 2*frame_extended+panel_length+2*seal_length,0,0) gmsh.model.occ.rotate(frame_surface_right, panel_length,0,0,0,0,1,math.pi/2) -gmsh.model.occ.translate(frame_surface_right, 0,-seal_length-frame_extended,0) +gmsh.model.occ.translate(frame_surface_right, 0,-2*seal_length-2*frame_extended,0) right_frame = gmsh.model.occ.extrude(frame_surface_right, 0,2*frame_extended+2*seal_length+panel_width,0) right_frame_tag = right_frame[1][1] +######################### # create the rear frame +########################## + frame_surface_rear = gmsh.model.occ.copy([(2,frame_surface_xz)]) -gmsh.model.occ.translate(frame_surface_rear,0, frame_extended+panel_width+2*seal_length,0) +gmsh.model.occ.translate(frame_surface_rear,0, 2*frame_extended+panel_width+2*seal_length,0) gmsh.model.occ.rotate(frame_surface_rear, 0,panel_width,0,0,0,1,-math.pi/2) -gmsh.model.occ.translate(frame_surface_rear,-seal_length-frame_extended, 0,0) +gmsh.model.occ.translate(frame_surface_rear,-2*seal_length-2*frame_extended, 0,0) rear_frame = gmsh.model.occ.extrude(frame_surface_rear, 2*frame_extended+panel_length+2*seal_length,0,0) - rear_frame_tag = rear_frame[1][1] - - """ cut the frame and remove extended parts """ +################################################### # create cutting surface at the left-front corner +################################################### + cut_surface_left_front_point1 = gmsh.model.occ.addPoint(-surface_extended, -surface_extended, -surface_extended) cut_surface_left_front_point2 = gmsh.model.occ.addPoint(surface_extended, surface_extended, -surface_extended) cut_surface_left_front_point3 = gmsh.model.occ.addPoint(surface_extended, surface_extended, surface_extended) @@ -277,12 +263,20 @@ def process_input_file(input_file_path): cut_surface_left_front = gmsh.model.occ.addPlaneSurface([cut_surface_left_front_curve_loop]) +################################################### # create cutting surface at the right-rear corner +################################################### + cut_surface_right_rear = gmsh.model.occ.copy([(2,cut_surface_left_front)]) + gmsh.model.occ.translate(cut_surface_right_rear,panel_length, panel_width,0) + cut_surface_right_rear_tag = cut_surface_right_rear[0][1] +################################################### # create cutting surface at the left-rear corner +################################################### + cut_surface_left_rear_point1 = gmsh.model.occ.addPoint(-surface_extended, panel_width+surface_extended, -surface_extended) cut_surface_left_rear_point2 = gmsh.model.occ.addPoint(surface_extended, panel_width-surface_extended, -surface_extended) cut_surface_left_rear_point3 = gmsh.model.occ.addPoint(surface_extended, panel_width-surface_extended, surface_extended) @@ -297,14 +291,22 @@ def process_input_file(input_file_path): cut_surface_left_rear = gmsh.model.occ.addPlaneSurface([cut_surface_left_rear_curve_loop]) +################################################### # create cutting surface at the right-front corner +################################################### + cut_surface_right_front = gmsh.model.occ.copy([(2,cut_surface_left_rear)]) gmsh.model.occ.translate(cut_surface_right_front,panel_length, -panel_width,0) cut_surface_right_front_tag = cut_surface_right_front[0][1] +################################################### # cut and remove the extended part of left frame +################################################### cutted_left_frame = gmsh.model.occ.fragment([(3,left_frame_tag)],[(2,cut_surface_left_front), (2,cut_surface_left_rear)], removeTool=False) + + + # remove the extended part of the frame gmsh.model.occ.remove([cutted_left_frame[0][0], cutted_left_frame[0][2]], recursive=True) # final tag of frame at left @@ -315,7 +317,12 @@ def process_input_file(input_file_path): remove_surface_list.append(cutted_left_frame[0][i]) gmsh.model.occ.remove(remove_surface_list, recursive=True) + + +################################################### # cut and remove the extended part of front frame +################################################### + cutted_front_frame = gmsh.model.occ.fragment([(3,front_frame_tag)],[(2,cut_surface_left_front), (2,cut_surface_right_front_tag)], removeTool=False) # remove the extended part of the frame gmsh.model.occ.remove([cutted_front_frame[0][0], cutted_front_frame[0][2]], recursive=True) @@ -327,7 +334,10 @@ def process_input_file(input_file_path): remove_surface_list.append(cutted_front_frame[0][i]) gmsh.model.occ.remove(remove_surface_list, recursive=True) +################################################### # cut and remove the extended part of right frame +################################################### + cutted_right_frame = gmsh.model.occ.fragment([(3,right_frame_tag)],[(2,cut_surface_right_front_tag), (2,cut_surface_right_rear_tag)], removeTool=False) # remove the extended part of the frame gmsh.model.occ.remove([cutted_right_frame[0][0], cutted_right_frame[0][2]], recursive=True) @@ -339,7 +349,10 @@ def process_input_file(input_file_path): remove_surface_list.append(cutted_right_frame[0][i]) gmsh.model.occ.remove(remove_surface_list, recursive=True) +################################################### # cut and remove the extended part of right frame +################################################### + cutted_rear_frame = gmsh.model.occ.fragment([(3,rear_frame_tag)],[(2,cut_surface_right_rear_tag), (2,cut_surface_left_rear)], removeTool=False) # remove the extended part of the frame gmsh.model.occ.remove([cutted_rear_frame[0][0], cutted_rear_frame[0][2]], recursive=True) @@ -356,48 +369,15 @@ def process_input_file(input_file_path): # remove interfaces between frames, all tags of frames are not changed gmsh.model.occ.fragment([(3, final_front_frame_tag),(3, final_rear_frame_tag)],[(3, final_left_frame_tag), (3, final_right_frame_tag)]) -gmsh.model.occ.synchronize() - - -# 4 -# =============== -# | | -# | | -# y 1 | | 3 -# | | -# =============== -# 2 -# x -# -# gmsh.model.occ.synchronize() -count_volumes=0 -count_surface = 0 - -# # capture surfaces -# surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) -# surf_list = surf_tag_list[count_surface:][:] -# count_surface = surface_tags(surf_list,count_surface,ndim) - -structure_vol_list =["frm0","frm1","frm2","frm3"] -# vol_tag_list = gmsh.model.occ.getEntities(ndim) -# vol_list = vol_tag_list[count_volumes:][:] -# count_volumes, structure_vol_list = volume_tags(vol_list,count_volumes,structure_vol_list) - -# min_dist=[] -# for volid in structure_vol_list: -# threshold = set_length_scale(volid, frame_thick*100, frame_thick*100, 0, 0 )#3 -# min_dist.append(threshold) - -# # gmsh.model.mesh.generate(3) +""" +create panel +""" +################################## +# create the panel (unpartitioned) +################################## -# gmsh.write("panel_geo.msh") -# gmsh.write("panel_geo.vtk") - -########################### -# create the panel -########################### # create backsheet back_sheet = gmsh.model.occ.addBox(0, 0, 0, panel_length, panel_width, back_sheet_thick) @@ -413,95 +393,423 @@ def process_input_file(input_file_path): # create front glass layer front_glass = gmsh.model.occ.addBox(0, 0, back_sheet_thick+back_encap_thick+cell_thick+front_encap_thick, panel_length, panel_width, front_glass_thick) + + +################################################################################################# +# since the top surface and bottom surface of the panel are partially covered by the seal, +# we partition the whole thickness of the panel to have a covered volume for each layer, +# so we can have a sweep mesh + +# partition of front glass: +################################################################################################# + +# create volume to partition front glass +z_start_cell_front_glass = back_sheet_thick+back_encap_thick+cell_thick+front_encap_thick + +# partition the glass into two parts, uncovered part and covered part +uncovered_glass = gmsh.model.occ.addBox(cover_length, cover_length, z_start_cell_front_glass, panel_length-2*cover_length, \ + panel_width-2*cover_length, front_glass_thick) +uncovered_front_glass_frag = gmsh.model.occ.fragment([(3,front_glass)],[(3,uncovered_glass)], removeTool=True) + +# uncovered_front_glass_frag[0][0][1] is uncovered part, uncovered_front_glass_frag[0][1][1] is the covered part + +cell_front_glass_list = [] +for i in range(n_cell_length): + for j in range(n_cell_width): + cell_tag = uncovered_front_glass_frag[0][1][1]+1+i*n_cell_width+j + x_cell = perimeter_margin+(cell_length+cell_cell_gap_x)*i + y_cell = perimeter_margin+(cell_width+cell_cell_gap_y)*j + gmsh.model.occ.addBox(x_cell, y_cell, z_start_cell_front_glass, cell_length, cell_width, front_glass_thick, tag=cell_tag) + cell_front_glass_list.append((3,cell_tag)) + +# partition of uncovered front_glass +cell_front_glass_frag = gmsh.model.occ.fragment([(3,uncovered_front_glass_frag[0][0][1])], cell_front_glass_list, removeTool=True) +front_glass_tag_list = cell_front_glass_frag[0] #list of vector, uncovered part +front_glass_tag_list.append(uncovered_front_glass_frag[0][1]) # covered part + +################################################### +# partition of front eva +################################################### + +# create volume to partition front eva +z_start_cell_front_eva = back_sheet_thick+back_encap_thick+cell_thick + +# partition the front_eva into two parts, uncovered part and covered part +uncovered_front_eva = gmsh.model.occ.addBox(cover_length, cover_length, z_start_cell_front_eva, panel_length-2*cover_length, \ + panel_width-2*cover_length, front_encap_thick) + +uncovered_front_eva_frag = gmsh.model.occ.fragment([(3,front_encap)],[(3,uncovered_front_eva)], removeTool=True) + +# uncovered_front_eva_frag[0][0][1] is uncovered part, uncovered_front_eva_frag[0][1][1] is the covered part + +cell_front_eva_list = [] +for i in range(n_cell_length): + for j in range(n_cell_width): + cell_tag = uncovered_front_eva_frag[0][1][1]+1+i*n_cell_width+j + x_cell = perimeter_margin+(cell_length+cell_cell_gap_x)*i + y_cell = perimeter_margin+(cell_width+cell_cell_gap_y)*j + gmsh.model.occ.addBox(x_cell, y_cell, z_start_cell_front_eva, cell_length, cell_width, front_encap_thick, tag=cell_tag) + cell_front_eva_list.append((3,cell_tag)) +# partition of front eva layer +cell_front_eva_frag = gmsh.model.occ.fragment([(3,uncovered_front_eva_frag[0][0][1])], cell_front_eva_list, removeTool=True) +front_encap_tag_list = cell_front_eva_frag[0] # list of vector +front_encap_tag_list.append(uncovered_front_eva_frag[0][1]) + + +################################################### +# partition of the back eva +################################################### + +# create volume to partition back eva +z_start_cell_back_eva = back_sheet_thick + +# partition the back_eva into two parts, uncovered part and covered part +uncovered_back_eva = gmsh.model.occ.addBox(cover_length, cover_length, z_start_cell_back_eva, panel_length-2*cover_length, \ + panel_width-2*cover_length, back_encap_thick) + +uncovered_back_eva_frag = gmsh.model.occ.fragment([(3,back_encap)],[(3,uncovered_back_eva)], removeTool=True) + +# uncovered_beack_eva_frag[0][0][1] is uncovered part, uncovered_back_eva_frag[0][1][1] is the covered part + +cell_back_eva_list = [] +for i in range(n_cell_length): + for j in range(n_cell_width): + cell_tag = uncovered_back_eva_frag[0][1][1]+1+i*n_cell_width+j + x_cell = perimeter_margin+(cell_length+cell_cell_gap_x)*i + y_cell = perimeter_margin+(cell_width+cell_cell_gap_y)*j + gmsh.model.occ.addBox(x_cell, y_cell, z_start_cell_back_eva, cell_length, cell_width, back_encap_thick, tag=cell_tag) + cell_back_eva_list.append((3,cell_tag)) +# partition of back eva layer +cell_back_eva_frag = gmsh.model.occ.fragment([(3,uncovered_back_eva_frag[0][0][1])], cell_back_eva_list, removeTool=True) +back_encap_tag_list = cell_back_eva_frag[0] # list of vector +back_encap_tag_list.append(uncovered_back_eva_frag[0][1]) + +################################################### +# partition of cell layer +################################################### + +# create volume to partition cell layer +z_start_cell_cell_layer = back_sheet_thick + back_encap_thick + +# partition the back_eva into two parts, uncovered part and covered part +uncovered_cell_layer = gmsh.model.occ.addBox(cover_length, cover_length, z_start_cell_cell_layer, panel_length-2*cover_length, \ + panel_width-2*cover_length, cell_thick) + +uncovered_cell_layer_frag = gmsh.model.occ.fragment([(3,cell_layer)],[(3,uncovered_cell_layer)], removeTool=True) + +# uncovered_cell_layer_frag[0][0][1] is uncovered part, uncovered_cell_layer_frag[0][1][1] is the covered part + # create cell -z_start_cell = back_sheet_thick+back_encap_thick cell_list = [] for i in range(n_cell_length): for j in range(n_cell_width): - cell_tag = front_glass+1+i*n_cell_width+j + cell_tag = uncovered_cell_layer_frag[0][1][1]+1+i*n_cell_width+j x_cell = perimeter_margin+(cell_length+cell_cell_gap_x)*i y_cell = perimeter_margin+(cell_width+cell_cell_gap_y)*j - gmsh.model.occ.addBox(x_cell, y_cell, z_start_cell, cell_length, cell_width, cell_thick, tag=cell_tag) + gmsh.model.occ.addBox(x_cell, y_cell, z_start_cell_cell_layer, cell_length, cell_width, cell_thick, tag=cell_tag) cell_list.append((3,cell_tag)) # remove repeated surfaces between cell and cell_layer, index of cells are not changed, index of residual cell_layer_eva is changed -cell_eva_frag = gmsh.model.occ.fragment([(3,cell_layer)], cell_list, removeTool=True) -cell_layer_encap_tag = cell_eva_frag[1][0][0][1] +cell_eva_frag = gmsh.model.occ.fragment([(3,uncovered_cell_layer_frag[0][0][1])], cell_list, removeTool=True) # cell_layer is partited to be 1+n_cell_length*n_cell_width, cell are partited into 2*n_cell_length*n_cell_width +whole_cell_layer = cell_eva_frag[1][0] # list of vector +whole_cell_layer.append(uncovered_cell_layer_frag[0][1]) # list of vector + +cell_layer_encap_tag = [x[1] for x in whole_cell_layer if x not in cell_list] # tag of eva domain in cell layer + + +# ################################################## +# partition of the back sheet +# ################################################## + +# create volume to partition back sheet +z_start_cell_back_sheet = 0 + +# partition the back_sheet into two parts, uncovered part and covered part +uncovered_back_sheet = gmsh.model.occ.addBox(cover_length, cover_length, z_start_cell_back_sheet, panel_length-2*cover_length, \ + panel_width-2*cover_length, back_sheet_thick) + +uncovered_back_sheet_frag = gmsh.model.occ.fragment([(3,back_sheet)],[(3,uncovered_back_sheet)], removeTool=True) + +# uncovered_back_sheet_frag[0][0][1] is uncovered part, uncovered_back_sheet_frag[0][1][1] is the covered part + +cell_back_sheet_list = [] +for i in range(n_cell_length): + for j in range(n_cell_width): + cell_tag = uncovered_back_sheet_frag[0][1][1]+1+i*n_cell_width+j + x_cell = perimeter_margin+(cell_length+cell_cell_gap_x)*i + y_cell = perimeter_margin+(cell_width+cell_cell_gap_y)*j + gmsh.model.occ.addBox(x_cell, y_cell, z_start_cell_back_sheet, cell_length, cell_width, back_sheet_thick, tag=cell_tag) + cell_back_sheet_list.append((3,cell_tag)) +#partition of back sheet +cell_back_sheet_frag = gmsh.model.occ.fragment([(3,uncovered_back_sheet_frag[0][0][1])], cell_back_sheet_list, removeTool=True) +back_sheet_tag_list = cell_back_sheet_frag[1][0] # list of vector +back_sheet_tag_list.append(uncovered_back_sheet_frag[0][1]) -gmsh.model.occ.fragment([(3,front_glass)], [(3,front_encap)], removeTool=True) # remove repeated interfaces, index of glass and front_enc are not changed -gmsh.model.occ.fragment([(3,front_encap)], cell_eva_frag[0], removeTool=True) # remove repeated interfaces, all index of involved volumes are not changed -gmsh.model.occ.fragment(cell_eva_frag[0], [(3,back_encap)], removeTool=True) # remove repeated interfaces, all index of involved volumes are not changed -gmsh.model.occ.fragment([(3,back_encap)], [(3,back_sheet)], removeTool=True) # index of each layer are not changed. -######################################### -# create seal layer geometry -######################################### +gmsh.model.occ.fragment(front_glass_tag_list, front_encap_tag_list, removeTool=True) # remove repeated interfaces, index of glass and front_enc are not changed +gmsh.model.occ.fragment(front_encap_tag_list, whole_cell_layer, removeTool=True) # remove repeated interfaces, all index of involved volumes are not changed +gmsh.model.occ.fragment(whole_cell_layer, back_encap_tag_list, removeTool=True) # remove repeated interfaces, all index of involved volumes are not changed +gmsh.model.occ.fragment(back_encap_tag_list, back_sheet_tag_list, removeTool=True) # index of each layer are not changed. + + + +""" +create seal layer geometry +""" +################### # create the seal +#################### seal_whole = gmsh.model.occ.addBox(-seal_length, -seal_length, -seal_thick, panel_length+2*seal_length, panel_width+2*seal_length, panel_thick+2*seal_thick) remove_seal_1 = gmsh.model.occ.addBox(cover_length, cover_length, -seal_thick, panel_length-2*(cover_length), panel_width-2*(cover_length), panel_thick+2*seal_thick) remove_seal_2 = gmsh.model.occ.addBox(0,0,0, panel_length, panel_width, panel_thick) seal = remove_seal_2+1 gmsh.model.occ.cut([(3, seal_whole)], [(3, remove_seal_1), (3, remove_seal_2)], tag = seal) +####################################### +# fragment to remove repeated surfaces +####################################### + # romove repeated interfaces between panel and seal, -gmsh.model.occ.fragment([(3,seal)],[(3, front_glass),(3, front_encap),(3, cell_layer_encap_tag),(3,back_encap),(3,back_sheet)], removeTool=True) +gmsh.model.occ.fragment([(3,seal)],front_glass_tag_list+front_encap_tag_list+whole_cell_layer+back_encap_tag_list+back_sheet_tag_list, removeTool=True) # remove interfaces between frame and seal, all volume index are not changd gmsh.model.occ.fragment([(3, final_front_frame_tag),(3, final_rear_frame_tag),(3, final_left_frame_tag), (3, final_right_frame_tag)],[(3,seal)], removeTool=True) +####################################### +# get tags of each layer +####################################### + +front_glass_tags = [] +for i in range (len(front_glass_tag_list)): + front_glass_tags.append(front_glass_tag_list[i][1]) + +front_encap_tags = [] +for i in range (len(front_encap_tag_list)): + front_encap_tags.append(front_encap_tag_list[i][1]) + +back_encap_tags = [] +for i in range (len(back_encap_tag_list)): + back_encap_tags.append(back_encap_tag_list[i][1]) + +back_sheet_tags = [] +for i in range (len(back_sheet_tag_list)): + back_sheet_tags.append(back_sheet_tag_list[i][1]) + +all_volume_list = [[final_left_frame_tag,final_front_frame_tag,final_right_frame_tag,final_rear_frame_tag], back_sheet_tags, back_encap_tags, front_encap_tags, front_glass_tags] + + +cell_tags = [] + +for i in range(int(n_cell_length*n_cell_width)): + cell_tags.append(cell_list[i][1]) + +all_volume_list.append(cell_tags) +all_volume_list.append(cell_layer_encap_tag) +all_volume_list.append([seal]) + + +number_volume_groups = len(all_volume_list) + +# all_volume_list +# [0]: volume tages of all frames, [0][0] left frame, [0][1] front frame, [0][2] right frame, [0][1] rear frame +# [1]: volume tages of back sheet +# [2]: volume tages of back encap +# [3]: volume tages of front encap +# [4]: volume tages of front glass +# [5]: volume tages of all cells +# [6]: volume tages of encapsulant in cell layer, [6][0] is the uncovered part, [6][1] is the covered part +# [7]: volume tages of seal layer + -# gmsh.model.occ.synchronize() gmsh.model.occ.synchronize() +gmsh.write("panel_geo.brep") -# # capture surfaces -surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) -surf_list = surf_tag_list[count_surface:][:] -count_surface = surface_tags(surf_list,count_surface,ndim) +""" +mark all surfaces and volumes and create physical groups for each surface and volume +""" +count_volumes_groups=0 +count_surface = 0 -vol_tag_list = gmsh.model.occ.getEntities(ndim) -vol_list = vol_tag_list[count_volumes:][:] -structure_vol_list +=["back_sheet","back_encap","front_encap","front_glass"] +domain_markers = {} # Must start indexing at 1, if starting at 0, things marked "0" + # are indistinguishable from things which receive no marking (and have default value of 0) +domain_markers["_current_idx"] = 1 -for i in range(n_cell_length): - for j in range(n_cell_width): - structure_vol_list.append("cell"+str(i*n_cell_width + j)) +# # capture surfaces +surf_tag_list = gmsh.model.occ.getEntities(ndim - 1) +count_surface = surface_tags(surf_tag_list,count_surface) -structure_vol_list.append("cell_layer_encap") -structure_vol_list.append("seal") -count_volumes, structure_vol_list = volume_tags(vol_list,count_volumes,structure_vol_list) +structure_vol_list =["frm"] # frm0 is left frame, frm1 is front frame, frm2 is right frame, frm3 is rear frame. +structure_vol_list +=["back_sheet","back_encap","front_encap","front_glass", "cell", "cell_layer_encap", "seal"] -from_domain_markers_to_PhysicalName(domain_markers,ndim) +count_volumes_groups = volume_tags(all_volume_list,count_volumes_groups,structure_vol_list, number_volume_groups) +# # domain_markers: current_idx:157, sur 100:{idx:100, tags: [100], type: facet}....front_glass:{idx: 1, tag: [20,21,3,4,3], type: cell} -min_dist = [] -for volid in structure_vol_list[0:4]: - threshold = set_length_scale(volid, frame_thick*1, frame_thick*10, 0, 0.1 )#3 - min_dist.append(threshold) +# add physical group for surface and volumes. physical group 1: (name: suf 1, physical group number 1) +from_domain_markers_to_PhysicalName(domain_markers, int(ndim)) -threshold = set_length_scale("back_sheet", back_sheet_thick*10 ,back_sheet_thick*100, 0, 0.1 )#3 -min_dist.append(threshold) -threshold = set_length_scale("back_encap", back_encap_thick*10 , back_encap_thick*100, 0, 0.1 )#3 -min_dist.append(threshold) -threshold = set_length_scale("front_encap", front_encap_thick*10 , front_encap_thick*100, 0, 0.1 )#3 -min_dist.append(threshold) -threshold = set_length_scale("front_glass", front_glass_thick*10, front_glass_thick*100, 0, 0.1 )#3 -min_dist.append(threshold) -for i in range(n_cell_length): - for j in range(n_cell_width): - threshold = set_length_scale("cell"+str(i*n_cell_width + j), cell_thick*.5, cell_thick*1, 0, .1 )#3 - min_dist.append(threshold) -threshold = set_length_scale("seal", seal_thick*10 , seal_thick*100, 0, 0.1 )#3 -min_dist.append(threshold) +""" +create mesh size field +""" +# ###################################### +# threshold field based ion distance (not using here) +# ###################################### + + +# # # # min_dist = [] +# # # # for volid in structure_vol_list[0:4]: # frames +# # # # threshold = set_length_scale(volid, frame_thick*1, frame_thick*10, 0, 0.1 )#3 +# # # # min_dist.append(threshold) + +# # # # threshold = set_length_scale("back_sheet", back_sheet_thick*10 ,back_sheet_thick*100, 0, 0.1 )#3 +# # # # min_dist.append(threshold) +# # # # threshold = set_length_scale("back_encap", back_encap_thick*10 , back_encap_thick*100, 0, 0.1 )#3 +# # # # min_dist.append(threshold) +# # # # threshold = set_length_scale("front_encap", front_encap_thick*10 , front_encap_thick*100, 0, 0.1 )#3 +# # # # min_dist.append(threshold) +# # # # threshold = set_length_scale("front_glass", front_glass_thick*10, front_glass_thick*100, 0, 0.1 )#3 +# # # # min_dist.append(threshold) + + +# # # # for i in range(n_cell_length): +# # # # for j in range(n_cell_width): +# # # # threshold = set_length_scale("cell"+str(i*n_cell_width + j), cell_thick*.5, cell_thick*1, 0, .1 )#3 +# # # # min_dist.append(threshold) + +# # # # threshold = set_length_scale("seal", seal_thick*10 , seal_thick*100, 0, 0.1 )#3 +# # # # min_dist.append(threshold) + +# # # # minimum = gmsh.model.mesh.field.add("Min") +# # # # gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", min_dist) # take the minimum value of a list of fields. +# # # # gmsh.model.mesh.field.setAsBackgroundMesh(minimum) # set the minimum field as the background mesh size field + + + + +# gmsh.option.setNumber('Mesh.MeshSizeMin', 0.001) +# gmsh.option.setNumber('Mesh.MeshSizeMax', 0.02) + + + +# define box field for the whole domain +box_field_list = [] +volume_field_whole_domain = gmsh.model.mesh.field.add("Box") +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "Thickness", frame_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "VIn", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "VOut", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "XMax", panel_length+seal_length+frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "XMin", -seal_length-frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "YMax", panel_width+seal_length+frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "YMin", -seal_length-frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "ZMax", panel_thick+seal_thick+frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_whole_domain, "ZMin", panel_thick+seal_thick+frame_thick-h) +box_field_list.append(volume_field_whole_domain) + +# define box field for the back sheet domain +volume_field_back_sheet = gmsh.model.mesh.field.add("Box") +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "Thickness", back_sheet_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "VIn", 3*back_sheet_thick) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "VOut", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "XMax", panel_length-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "XMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "YMax", panel_width-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "YMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "ZMax", back_sheet_thick) +gmsh.model.mesh.field.setNumber(volume_field_back_sheet, "ZMin", 0) +box_field_list.append(volume_field_back_sheet) + +# define box field for the back EVA domain +volume_field_back_eva = gmsh.model.mesh.field.add("Box") +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "Thickness", back_encap_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "VIn", 3*back_encap_thick) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "VOut", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "XMax", panel_length-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "XMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "YMax", panel_width-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "YMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "ZMax", back_sheet_thick+back_encap_thick) +gmsh.model.mesh.field.setNumber(volume_field_back_eva, "ZMin", back_sheet_thick) +box_field_list.append(volume_field_back_eva) + +# define box field for the cell layer domain +volume_field_cell_layer = gmsh.model.mesh.field.add("Box") +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "Thickness", cell_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "VIn", 3*cell_thick) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "VOut", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "XMax", panel_length-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "XMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "YMax", panel_width-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "YMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "ZMax", back_sheet_thick+back_encap_thick+cell_thick) +gmsh.model.mesh.field.setNumber(volume_field_cell_layer, "ZMin", back_sheet_thick+back_encap_thick) +box_field_list.append(volume_field_cell_layer) + +# define box field for the front eva domain +volume_field_front_eva = gmsh.model.mesh.field.add("Box") +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "Thickness", front_encap_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "VIn", 3*back_encap_thick) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "VOut", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "XMax", panel_length-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "XMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "YMax", panel_width-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "YMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "ZMax", back_sheet_thick+back_encap_thick+cell_thick+front_encap_thick) +gmsh.model.mesh.field.setNumber(volume_field_front_eva, "ZMin", back_sheet_thick+back_encap_thick+cell_thick) +box_field_list.append(volume_field_front_eva) + +# define box field for the front glass domain +volume_field_front_glass = gmsh.model.mesh.field.add("Box") +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "Thickness", front_glass_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "VIn", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "VOut", 3*frame_thick) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "XMax", panel_length-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "XMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "YMax", panel_width-cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "YMin", cover_length) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "ZMax", panel_thick) +gmsh.model.mesh.field.setNumber(volume_field_front_glass, "ZMin", back_sheet_thick+back_encap_thick+cell_thick+front_encap_thick) +box_field_list.append(volume_field_front_eva) + +# # # # define box field for uncovered panel part +# # # uncovered_volume_field = gmsh.model.mesh.field.add("Box") +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "Thickness", frame_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "VOut", frame_thick) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "VIn", frame_thick) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "XMin", cover_length) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "XMax", panel_length-2*cover_length) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "YMin", cover_length) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "YMax", panel_width-2*cover_length) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "ZMax", panel_thick) +# # # gmsh.model.mesh.field.setNumber(uncovered_volume_field, "ZMin", 0) +# # # box_field_list.append(uncovered_volume_field) + +# # # # define box field for cells, box will go across whole thickness of panel +# # # for i in range(n_cell_length): +# # # for j in range(n_cell_width): +# # # cell_volume_field = gmsh.model.mesh.field.add("Box") +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "Thickness", -10*frame_thick) # the mesh size is interpolated between VIn and VOut in a layer around the box of the prescribed thickness. +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "VOut", frame_thick) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "VIn", cell_thick) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "XMin", perimeter_margin+(cell_length+cell_cell_gap_x)*i) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "XMax", perimeter_margin+(cell_length+cell_cell_gap_x)*i+cell_length) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "YMin", perimeter_margin+(cell_width+cell_cell_gap_y)*j) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "YMax", perimeter_margin+(cell_width+cell_cell_gap_y)*j+cell_width) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "ZMax", panel_thick) +# # # gmsh.model.mesh.field.setNumber(cell_volume_field, "ZMin", 0) +# # # box_field_list.append(cell_volume_field) minimum = gmsh.model.mesh.field.add("Min") -gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", min_dist) -gmsh.model.mesh.field.setAsBackgroundMesh(minimum) +gmsh.model.mesh.field.setNumbers(minimum, "FieldsList", box_field_list) # take the minimum value of a list of fields. +gmsh.model.mesh.field.setAsBackgroundMesh(minimum) # set the minimum field as the background mesh size field + +# gmsh.model.mesh.setTransfiniteAutomatic() +gmsh.option.setNumber("Mesh.ToleranceInitialDelaunay", 1e-12) gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0) gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0) @@ -513,9 +821,21 @@ def process_input_file(input_file_path): gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 0) gmsh.model.mesh.setOrder(1) +# gmsh.model.mesh.optimize('Netgen') gmsh.model.mesh.generate(3) -gmsh.write("panel_geo.msh") -gmsh.write("panel_geo.vtk") + + +gmsh.write("panel_geo.msh") # for ansys +gmsh.write("panel_geo.vtk") # for fenics? +# gmsh.write("panel_geo.stl") +# gmsh.write("panel_geo.inp") # for ansys, abaqus +# gmsh.write("panel_geo.dat") # for ansys +# gmsh.write("panel_geo.wrl") +gmsh.write("panel_geo.bdf") # bdf file for comsol gmsh.finalize() + + + +