def createTopoProblem(props, forest, order=2, nlevels=2, Xscale=1.0, ordering=TACS.PY_MULTICOLOR_ORDER): # Create the forest forests = [] filters = [] assemblers = [] varmaps = [] vecindices = [] # Create the trees, rebalance the elements and repartition forest.balance(1) forest.repartition() forests.append(forest) # Create the filter filtr = forest.coarsen() filtr.balance(1) filters.append(filtr) # Make the creator class creator = CreateMe(bcs, filters[-1], props) assemblers.append( creator.createTACS(forest, scale=Xscale, ordering=ordering)) varmaps.append(creator.getMap()) vecindices.append(creator.getIndices()) for i in range(nlevels - 1): forest = forests[-1].coarsen() forest.balance(1) forest.repartition() forests.append(forest) # Create the filter filtr = forest.coarsen() filtr.balance(1) filters.append(filtr) # Make the creator class creator = CreateMe(bcs, filters[-1], props) assemblers.append( creator.createTACS(forest, scale=Xscale, ordering=ordering)) varmaps.append(creator.getMap()) vecindices.append(creator.getIndices()) # Create the multigrid object mg = TMR.createMg(assemblers, forests) # Create the topology optimization problem vars_per_node = 1 nmats = props.getNumMaterials() if nmats > 1: vars_per_node = nmats + 1 problem = TMR.TopoProblem(assemblers, filters, varmaps, vecindices, mg, vars_per_node) return assemblers[0], problem, filters[0], varmaps[0]
def create_forest(comm, depth): """ Create an initial forest for analysis. and optimization This code loads in the model, sets names, meshes the geometry and creates a QuadForest from the mesh. The forest is populated with quadtrees with the specified depth. Args: comm (MPI_Comm): MPI communicator depth (int): Depth of the initial trees htarget (float): Target global element mesh size Returns: OctForest: Initial forest for topology optimization """ # Load the geometry model geo = TMR.LoadModel('cantilever.stp') # Mark the boundary condition faces verts = geo.getVertices() faces = geo.getFaces() volumes = geo.getVolumes() # Set source and target faces faces[3].setName('fixed') faces[4].setSource(volumes[0], faces[5]) verts[4].setName('pt1') verts[3].setName('pt2') # Create the mesh mesh = TMR.Mesh(comm, geo) # Set the meshing options opts = TMR.MeshOptions() # Create the surface mesh htarget = 5.0 mesh.mesh(htarget, opts) # Create a model from the mesh model = mesh.createModelFromMesh() # Create the corresponding mesh topology from the mesh-model topo = TMR.Topology(comm, model) # Create the quad forest and set the topology of the forest forest = TMR.OctForest(comm) forest.setTopology(topo) # Create the trees, rebalance the elements and repartition forest.createTrees(depth) return forest
def create_forest(comm, depth, htarget): """ Create an initial forest for analysis. and optimization This code loads in the model, sets names, meshes the geometry and creates a QuadForest from the mesh. The forest is populated with quadtrees with the specified depth. Args: comm (MPI_Comm): MPI communicator depth (int): Depth of the initial trees htarget (float): Target global element mesh size Returns: QuadForest: Initial forest for topology optimization """ # Load the geometry model geo = TMR.LoadModel('biclamped_traction.stp') # Mark the boundary condition faces verts = geo.getVertices() edges = geo.getEdges() faces = geo.getFaces() edges[1].setName('fixed') edges[9].setName('fixed') edges[4].setName('traction') # Create the mesh mesh = TMR.Mesh(comm, geo) # Set the meshing options opts = TMR.MeshOptions() # Create the surface mesh mesh.mesh(htarget, opts) # Create a model from the mesh model = mesh.createModelFromMesh() # Create the corresponding mesh topology from the mesh-model topo = TMR.Topology(comm, model) # Create the quad forest and set the topology of the forest forest = TMR.QuadForest(comm) forest.setTopology(topo) # Set parameters for later usage forest.createTrees(depth) return forest
def createTopoProblem(forest, order=2, nlevels=2): # Create the forest forests = [] filters = [] assemblers = [] varmaps = [] vecindices = [] # Create the trees, rebalance the elements and repartition forest.balance(1) forest.repartition() forests.append(forest) # Create the filter filtr = forest.coarsen() filtr.balance(1) filters.append(filtr) # Make the creator class creator = CreateMe(bcs, filters[-1]) assemblers.append(creator.createTACS(order, forest)) varmaps.append(creator.getMap()) vecindices.append(creator.getIndices()) for i in range(nlevels - 1): forest = forests[-1].coarsen() forest.balance(1) forest.repartition() forests.append(forest) # Create the filter filtr = forest.coarsen() filtr.balance(1) filters.append(filtr) # Make the creator class creator = CreateMe(bcs, filters[-1]) assemblers.append(creator.createTACS(order, forest)) varmaps.append(creator.getMap()) vecindices.append(creator.getIndices()) # Create the multigrid object mg = TMR.createMg(assemblers, forests) # Create the topology optimization problem problem = TMR.TopoProblem(assemblers, filters, varmaps, vecindices, mg) return assemblers[0], problem, filters[0], varmaps[0]
def createMg(self, forest, nlevels=2, order=3): # Create the forest forest.balance(1) forest.repartition() forest.setMeshOrder(order) # Create the forests forests = [forest] assemblers = [self.createTACS(forest)] if order == 3: forests.append(forests[-1].duplicate()) forests[-1].balance(1) forests[-1].repartition() forests[-1].setMeshOrder(2) assemblers.append(self.createTACS(forests[-1])) for i in range(nlevels - 1): forests.append(forests[-1].coarsen()) forests[-1].balance(1) forests[-1].repartition() forests[-1].setMeshOrder(2) assemblers.append(self.createTACS(forests[-1])) # Create the multigrid object mg = TMR.createMg(assemblers, forests) return assemblers[0], mg
def createElement(self, order, quadrant, index, weights): '''Create the element''' rho = 2600.0 E = 70e9 nu = 0.3 stiff = TMR.QuadStiffness(rho, E, nu, index, weights, q=5.0) elem = elements.PlaneQuad(2, stiff) return elem
def createElement(self, order, octant, index, weights): '''Create the element''' rho = 2600.0 E = 70e9 nu = 0.3 stiff = TMR.OctStiffness(rho, E, nu, index, weights, q=8.0) elem = elements.Solid(2, stiff) return elem
def interpolateDesignVec(orig_filter, orig_vec, new_filter, new_vec): """ This function interpolates a design vector from the original design space defined on an OctForest or QuadForest and interpolates it to a new OctForest or QuadForest. This function is used after a mesh adaptation step to get the new design space. Args: orig_filter (OctForest or QuadForest): Original filter Oct or QuadForest object orig_vec (PVec): Design variables on the original mesh in a ParOpt.PVec new_filter (OctForest or QuadForest): New filter Oct or QuadForest object new_vec (PVec): Design variables on the new mesh in a ParOpt.PVec (set on ouput) """ # Convert the PVec class to TACSBVec orig_x = TMR.convertPVecToVec(orig_vec) if orig_x is None: raise ValueError( 'Original vector must be generated by TMR.TopoProblem') new_x = TMR.convertPVecToVec(new_vec) if new_x is None: raise ValueError('New vector must be generated by TMR.TopoProblem') if orig_x.getVarsPerNode() != new_x.getVarsPerNode(): raise ValueError('Number of variables per node must be consistent') orig_varmap = orig_x.getVarMap() new_varmap = new_x.getVarMap() vars_per_node = orig_x.getVarsPerNode() # Create the interpolation class interp = TACS.VecInterp(orig_varmap, new_varmap, vars_per_node) new_filter.createInterpolation(orig_filter, interp) interp.initialize() # Perform the interpolation interp.mult(orig_x, new_x) return
def createProblem(forest, bcs, ordering, mesh_order=2, nlevels=2, pttype=TMR.GAUSS_LOBATTO_POINTS): # Create the forest forests = [] assemblers = [] # Create the trees, rebalance the elements and repartition forest.balance(1) forest.setMeshOrder(mesh_order, pttype) forest.repartition() forests.append(forest) # Make the creator class creator = CreateMe(bcs) assemblers.append(creator.createTACS(forest, ordering)) while mesh_order > 2: mesh_order = mesh_order - 1 forest = forests[-1].duplicate() forest.balance(1) forest.setMeshOrder(mesh_order, pttype) forests.append(forest) # Make the creator class creator = CreateMe(bcs) assemblers.append(creator.createTACS(forest, ordering)) for i in range(nlevels - 1): forest = forests[-1].coarsen() forest.setMeshOrder(2, pttype) forest.balance(1) forest.repartition() forests.append(forest) # Make the creator class creator = CreateMe(bcs) assemblers.append(creator.createTACS(forest, ordering)) # Create the multigrid object mg = TMR.createMg(assemblers, forests, use_coarse_direct_solve=True, use_chebyshev_smoother=False) return assemblers[0], mg
def createElement(self, order, quadrant, index, filtr): """ Create the element for the specified quadrant Args: order (int): The order of the element quadrant (TMR.Quadrant): The quadrant to be build for this element index (list): The global numbers for the quadrant nodes filtr (QuadForest): The QuadForest for the filter Returns: TACS.Element: Element to place within the Assembler """ stiff = TMR.ThermoQuadStiffness(self.props, index, None, filtr) elem = elements.PSThermoelasticQuad(order, stiff) return elem
def load_model(): geo = TMR.LoadModel('beam.step') # Get the faces/volume from the model faces = geo.getFaces() edges = geo.getEdges() verts = geo.getVertices() vols = geo.getVolumes() # Set the names faces[6].setName('hole') faces[7].setName('hole') faces[0].setName('fixed') # Set the source/destination faces faces[1].setSource(vols[0], faces[3]) return geo
def createElement(self, order, octant, index, weights): """ Create the element for the given octant. This callback provides the global indices for the filter mesh and the weights applied to each nodal density value to obtain the element density. The local octant is also provided (but not used here). Args: order (int): Order of the underlying mesh octant (Octant): The TMR.Octant class index (list): List of the global node numbers referenced by the element weights (list): List of weights to compute the element density Returns: TACS.Element: Element for the given octant """ stiff = TMR.OctStiffness(self.props, index, weights) elem = elements.Solid(2, stiff) return elem
def createProblemMg(topo, elem_dict, forest, bcs, ordering, order=2, nlevels=2, pttype=TMR.UNIFORM_POINTS): # Create the forest forests = [] assemblers = [] # Create the trees, rebalance the elements and repartition forest.balance(1) forest.setMeshOrder(order, pttype) forest.repartition() forests.append(forest) # Make the creator class creator = CreateMe(bcs, topo, elem_dict) assemblers.append(creator.createTACS(forest, ordering)) while order > 2: order = order - 1 forest = forests[-1].duplicate() forest.setMeshOrder(order, pttype) forest.balance(1) forests.append(forest) # Make the creator class creator = CreateMe(bcs, topo, elem_dict) assemblers.append(creator.createTACS(forest, ordering)) # Create the multigrid object mg = TMR.createMg(assemblers, forests, omega=0.5) return assemblers[0], mg
def load_model(): geo = TMR.LoadModel('model.step') # Get the faces/volume from the model faces = geo.getFaces() edges = geo.getEdges() verts = geo.getVertices() # Create the edge loops elist = [edges[3], edges[5], edges[45], edges[32]] ex, dx, vx = get_edge_dirs_verts(elist) elist = [edges[45], edges[6], edges[7], edges[51]] ey, dy, vy = get_edge_dirs_verts(elist) elist = [edges[2], edges[32], edges[51], edges[8]] ez, dz, vz = get_edge_dirs_verts(elist) # Create the faces fx = TMR.TFIFace(ex, dx, vx) fy = TMR.TFIFace(ey, dy, vy) fz = TMR.TFIFace(ez, dz, vz) faces.extend([fx, fy, fz]) # Make the volumes s1 = [fx, faces[3], faces[19], faces[6], faces[10], faces[9], faces[11], faces[12]] d1 = [1, -1, -1, -1, 1, 1, -1, -1] s2 = [fy, faces[16], faces[8], faces[5], faces[23], faces[15], faces[17], faces[18]] d2 = [-1, 1, -1, -1, 1, 1, -1, -1] s3 = [fz, faces[4], faces[20], faces[13], faces[7], faces[14], faces[21], faces[22]] d3 = [1, -1, 1, 1, 1, 1, -1, -1] s4 = [fx, fy, fz, faces[0], faces[1], faces[2]] d4 = [-1, 1, -1, -1, -1, -1] # Set the names faces[11].setName('fx') faces[12].setName('fx') faces[17].setName('fy') faces[18].setName('fy') faces[21].setName('fz') faces[22].setName('fz') # Form the 4 independent bodies that are connected through v1 = TMR.Volume(s1, d1) v2 = TMR.Volume(s2, d2) v3 = TMR.Volume(s3, d3) v4 = TMR.Volume(s4, d4) vols = [v1, v2, v3, v4] # Set the source/destination faces faces[19].setSource(v1, faces[3]) faces[5].setSource(v2, faces[23]) faces[7].setSource(v3, faces[13]) faces[1].setSource(v4, fz) # Create a new model geo = TMR.Model(verts, edges, faces, vols) return geo
faces[7].setSource(v3, faces[13]) faces[1].setSource(v4, fz) # Create a new model geo = TMR.Model(verts, edges, faces, vols) return geo # The communicator comm = MPI.COMM_WORLD # Load the geometry model geo = load_model() # Set the boundary conditions for the problem bcs = TMR.BoundaryConditions() bcs.addBoundaryCondition('fz') # Create the mesh mesh = TMR.Mesh(comm, geo) # Set the meshing options opts = TMR.MeshOptions() opts.frontal_quality_factor = 1.25 opts.num_smoothing_steps = 50 opts.triangularize_print_iter = 50000 opts.write_mesh_quality_histogram = 1 # Create the surface mesh mesh.mesh(0.02, opts)
x1 = np.zeros((n, 3)) for i in range(n): x1[i], xt, xtt = edge_list[k].evaluate(xi[i]) r, p = edge_list[k + 1].getRange() xi = r[0] + (r[1] - r[0]) * (0.5 * (1.0 - np.cos(np.pi * np.linspace(0, 1.0, n)))) # xi = xi[1:] x2 = np.zeros((n, 3)) for i in range(n): x2[i], xt, xtt = edge_list[k + 1].evaluate(xi[i]) x = np.vstack((x1, x2)) x[:, 1] = yloc[k // 2] interp = TMR.CurveInterpolation(x) interp.setNumControlPoints(nctl) curve = interp.createCurve(4) top, bottom = curve.split(0.5) top_curves.append(top) bottom_curves.append(bottom) # Loft the curves top_lofter = TMR.CurveLofter(top_curves) top_surface = top_lofter.createSurface(2) bottom_lofter = TMR.CurveLofter(bottom_curves) bottom_surface = bottom_lofter.createSurface(2) face_list = []
order = 2 elif order > 5: order = 5 # Set the type of ordering to use for this problem ordering = args.ordering ordering = ordering.lower() # Set the filename filename = 'crank.stp' # Set the value of the target length scale in the mesh htarget = args.htarget # Load the geometry model geo = TMR.LoadModel(filename) # Set the source/target meshes faces = geo.getFaces() vols = geo.getVolumes() faces[7].setSource(vols[0], faces[6]) # Set the names v0 = None faces[4].setName('fixed') for i in range(faces[4].getNumEdgeLoops()): eloop = faces[4].getEdgeLoop(i) edges, d = eloop.getEdgeLoop() for e in edges: e.setName('fixed') v1, v2 = e.getVertices()
p.add_argument('--opt_barrier_power', type=float, default=1.0) p.add_argument('--output_freq', type=int, default=1) p.add_argument('--init_depth', type=int, default=2) p.add_argument('--mg_levels', type=int, nargs='+', default=[2, 3]) p.add_argument('--max_lbfgs', type=int, default=10) p.add_argument('--hessian_reset', type=int, default=10) args = p.parse_args() # Set the parameter to use paropt or MMA use_paropt = False # The communicator comm = MPI.COMM_WORLD # Load the geometry model geo = TMR.LoadModel('beam2d.stp') # Mark the boundary condition faces verts = geo.getVertices() edges = geo.getEdges() volumes = geo.getVolumes() edges[1].setAttribute('fixed') verts[0].setAttribute('pt1') # Set the boundary conditions for the problem bcs = TMR.BoundaryConditions() bcs.addBoundaryCondition('fixed') # Create the mesh mesh = TMR.Mesh(comm, geo)
b1 = ctx.makeSolidBody(egads.BOX, rdata=[x, d]) x = [0, 0, 0.5] d = [0.5, 0.5, 0.5] b2 = ctx.makeSolidBody(egads.BOX, rdata=[x, d]) # Write out to a EGADS file m1 = ctx.makeTopology(egads.MODEL, children=[b1]) m2 = ctx.makeTopology(egads.MODEL, children=[b2]) m1.saveModel('box1.egads', overwrite=True) m2.saveModel('box2.egads', overwrite=True) comm = MPI.COMM_WORLD htarget = 0.05 geo1 = TMR.LoadModel('box1.egads', print_lev=1) geo2 = TMR.LoadModel('box2.egads', print_lev=1) findMatchingFaces(geo1, geo2) verts = [] edges = [] faces = [] vols = [] for geo in [geo1, geo2]: f = geo.getFaces() v = geo.getVolumes() # f[2].setSource(v[0], f[3]) verts.extend(geo.getVertices()) edges.extend(geo.getEdges())
kcond = [130.0*thickness, 65.0*thickness] ys = [450e6*thickness, 275e6*thickness] # Set the fixed mass max_density = sum(rho)/len(rho) initial_mass = vol*max_density m_fixed = vol_frac*initial_mass # Set the number of variables per node design_vars_per_node = 1 if (len(rho) > 1): design_vars_per_node = 1+len(rho) # Create the stiffness properties object props = TMR.QuadStiffnessProperties(rho, E, nu, _aT=aT, _kcond=kcond, k0=1e-3, eps=0.2, q=args.q_penalty, qtemp=0.0, qcond=0.0) # Set the boundary conditions for the problem bcs = TMR.BoundaryConditions() bcs.addBoundaryCondition('fixed', [0, 1, 2], [0.0, 0.0, 0.0]) time_array = np.zeros(sum(args.max_opt_iters[:])) t0 = MPI.Wtime() # Create the initial forest forest = create_forest(comm, args.init_depth, args.htarget) forest.setMeshOrder(args.order, TMR.GAUSS_LOBATTO_POINTS) # Set the original filter to NULL orig_filter = None
def createUniqueList(P1, P2, P3, tol=1e-5): ''' Create unique list of nodes Input: P1: Node 1 of triangle P2: Node 2 of triangle P3: Node 3 of triangle Output: unique_nodes: Unique list of nodes in structure conn: Elemental connectivity node_conn: Adjacency matrix ''' # Tolerance for uniqueness Xpts = np.vstack((P1, P2, P3)) loc = TMR.PointLocator(Xpts) node_nums = -np.ones(Xpts.shape[0], dtype='intc') # Locate the closest K points K = 20 index = np.zeros(K, dtype='intc') dist = np.zeros(K) unique_node = 0 for row in range(Xpts.shape[0]): if node_nums[row] < 0: # Locate the closest points and label them with # the same index loc.locateClosest(Xpts[row, :], index, dist) for k in range(K): if np.sqrt(dist[k]) < tol: node_nums[index[k]] = unique_node else: break # If we ordered one node, increment the counter if dist[0] < tol: unique_node += 1 # Create the unique list of nodes unique_nodes = np.zeros((unique_node, 3)) for row in range(Xpts.shape[0]): unique_nodes[node_nums[row], :] = Xpts[row, :] # Create the connectivity conn = np.zeros((P1.shape[0], 3), dtype='intc') for row in range(P1.shape[0]): conn[row, 0] = node_nums[row] conn[row, 1] = node_nums[row + P1.shape[0]] conn[row, 2] = node_nums[row + 2 * P1.shape[0]] # Return node connectivity (adjacency matrix) node_conn = [[] for x in range(unique_node)] # Loop over each triangle and add the connectivity for k in range(conn.shape[0]): u = conn[k, 0] v = conn[k, 1] w = conn[k, 2] if u < v: node_conn[u].append(v) if v < w: node_conn[v].append(w) if u < w: node_conn[u].append(w) return unique_nodes, conn, node_conn
x = [0, 0, 0.5] d = [0.5, 0.5, 0.5] b2 = ctx.makeSolidBody(egads.BOX, rdata=[x, d]) # Write out to a STEP file m1 = ctx.makeTopology(egads.MODEL, children=[b1]) m2 = ctx.makeTopology(egads.MODEL, children=[b2]) # Save the egads models m1.saveModel('box1.egads', overwrite=True) m2.saveModel('box2.egads', overwrite=True) comm = MPI.COMM_WORLD htarget = 0.25 geo1 = TMR.LoadModel('box1.egads', print_lev=1) geo2 = TMR.LoadModel('box2.egads', print_lev=1) TMR.setMatchingFaces([geo1, geo2]) verts = [] edges = [] faces = [] vols = [] # sfi = [0, 4] for i, geo in enumerate([geo1, geo2]): vols = geo.getVolumes() fail = vols[0].setExtrudeFaces() if fail: print("setExtrudeFaces failed for volume {}".format(i))
p.add_argument('--output', type=str, default='surface-mesh.vtk', help='output file name') args = p.parse_args() # Get the value of the filename filename = args.filename if not os.path.isfile(filename): raise ValueError('File %s does not exist' % (filename)) # Set the value of the target length scale in the mesh htarget = args.htarget # Load the geometry model geo = TMR.LoadModel(filename) geo.writeModelToTecplot('tecplot_surfaces.dat') # Create a model by discarding the volumes verts = geo.getVertices() edges = geo.getEdges() faces = geo.getFaces() geo_new = TMR.Model(verts, edges, faces) # Create the new mesh mesh = TMR.Mesh(comm, geo_new) # Set the meshing options opts = TMR.MeshOptions() opts.frontal_quality_factor = 1.25 opts.num_smoothing_steps = 10
d.text((2, -2), 'TMR', font=fnt, fill=(0, 0, 0)) img.save('tmr.png') pixels = list(img.getdata()) pixels = [pixels[i * width:(i + 1) * width] for i in range(height)] # Set the bounding box for now xlow = [0.0, 0.0, -5.0] xhigh = [width, height, 5.0] # Set hmin/hmax hmin = 0.15 hmax = 0.5 h = 0.25 # Create a box box = TMR.BoxFeatureSize(xlow, xhigh, hmin, hmax) cutoff = 128 for j in range(height): for i in range(width): (R, G, B) = pixels[j][i] gscale = (0.3 * R) + (0.59 * G) + (0.11 * B) if gscale < cutoff: xlow = [i, height - j, -1] xhigh = [i + 1, height - (j + 1), 1] box.addBox(xlow, xhigh, h) # Set the number of load cases nu = 2 nv = 2 x = [0.0, width]
from mpi4py import MPI from tmr import TMR import argparse # Create the communicator comm = MPI.COMM_WORLD # Create an argument parser to read in command-line arguments p = argparse.ArgumentParser() p.add_argument('--reverse', default=False, action='store_true') args = p.parse_args() # Load the model from the STEP file geo = TMR.LoadModel('first-section.stp') # Get the volumes vols = geo.getVolumes() # Get the edges/faces from the geometry faces = geo.getFaces() edges = geo.getEdges() # Set the source/target relationships if args.reverse: faces[4].setSource(vols[0], faces[5]) else: faces[5].setSource(vols[0], faces[4]) edges[8].setSource(edges[5]) # Create the geometry mesh = TMR.Mesh(comm, geo)
def createElement(self, order, octant, index, weights): '''Create the element''' stiff = TMR.OctStiffness(self.props, index, weights) elem = elements.Solid(2, stiff) return elem
else: verts = [v1, v2, v3, v4] edges = [edge1, edge2, edge3, edge4] faces = [face] # Create the TMRModel geo = TMR.Model(verts, edges, faces) return geo geo = create_panel(100.0, 100.0, use_hole=True) # Create the mesh comm = MPI.COMM_WORLD mesh = TMR.Mesh(comm, geo) # Mesh the part opts = TMR.MeshOptions() opts.num_smoothing_steps = 20 opts.write_mesh_quality_histogram = 1 # Mesh the geometry with the given target size htarget = 10.0 mesh.mesh(htarget, opts=opts) mesh.writeToVTK('surface-mesh.vtk') # Create a model from the mesh model = mesh.createModelFromMesh() # Create the corresponding mesh topology from the mesh-model
# Set the parameter to use paropt or MMA use_paropt = True use_jd = False use_tr = False if args.use_mma: use_paropt = False if args.use_jd: use_jd = True if args.use_tr: use_tr = True use_paropt = False # The communicator comm = MPI.COMM_WORLD # Load the geometry model geo = TMR.LoadModel('beam.stp') # Mark the boundary condition faces verts = geo.getVertices() faces = geo.getFaces() volumes = geo.getVolumes() faces[3].setAttribute('fixed') faces[4].setSource(volumes[0], faces[5]) verts[4].setAttribute('pt1') verts[3].setAttribute('pt2') # Set the boundary conditions for the problem bcs = TMR.BoundaryConditions() bcs.addBoundaryCondition('fixed') # Create the mesh
def create_panel(Lx, Ly, use_hole=True): ''' Create a panel with a whole in it ''' # Set the number of load cases nu = 2 nv = 2 x = np.linspace(-0.5 * Lx, 0.5 * Lx, nu) y = np.linspace(-0.5 * Ly, 0.5 * Ly, nv) pts = np.zeros((nu, nv, 3)) for j in range(nv): for i in range(nu): pts[i, j, 0] = x[i] pts[i, j, 1] = y[j] # Create the b-spline surface surf = TMR.BsplineSurface(pts) face = TMR.FaceFromSurface(surf) r = 0.2 c = 0.5 v1 = TMR.VertexFromFace(face, 0.0, 0.0) v2 = TMR.VertexFromFace(face, 1.0, 0.0) v3 = TMR.VertexFromFace(face, 1.0, 1.0) v4 = TMR.VertexFromFace(face, 0.0, 1.0) v5 = TMR.VertexFromFace(face, c - r, c) # Set up the first edge pcurve1 = TMR.BsplinePcurve(np.array([[0.0, 0.0], [1.0, 0.0]])) edge1 = TMR.EdgeFromFace(face, pcurve1) edge1.setVertices(v1, v2) edge1.setAttribute('y-') # Set up the first edge pcurve2 = TMR.BsplinePcurve(np.array([[1.0, 0.0], [1.0, 1.0]])) edge2 = TMR.EdgeFromFace(face, pcurve2) edge2.setVertices(v2, v3) edge2.setAttribute('x+') # Set up the first edge pcurve3 = TMR.BsplinePcurve(np.array([[1.0, 1.0], [0.0, 1.0]])) edge3 = TMR.EdgeFromFace(face, pcurve3) edge3.setVertices(v3, v4) edge3.setAttribute('y+') # Set up the first edge pcurve4 = TMR.BsplinePcurve(np.array([[0.0, 1.0], [0.0, 0.0]])) edge4 = TMR.EdgeFromFace(face, pcurve4) edge4.setVertices(v4, v1) edge4.setAttribute('x-') # Create the inner edge loop # (c-r, c+r) -- (c, c+r) -- (c+r, c+r) # | | # | | # (c-r, c) (c+r, c) # | | # | | # (c-r, c-r) -- (c, c-r) -- (c+r, c-r) pts = [[c - r, c], [c - r, c + r], [c, c + r], [c + r, c + r], [c + r, c], [c + r, c - r], [c, c - r], [c - r, c - r], [c - r, c]] wts = [ 1.0, 1.0 / np.sqrt(2), 1.0, 1.0 / np.sqrt(2), 1.0, 1.0 / np.sqrt(2), 1.0, 1.0 / np.sqrt(2), 1.0 ] Tu = [0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1.0, 1.0, 1.0] pcurve5 = TMR.BsplinePcurve(np.array(pts), tu=np.array(Tu), wts=np.array(wts), k=3) edge5 = TMR.EdgeFromFace(face, pcurve5) edge5.setVertices(v5, v5) # Create the loop dirs = [1, 1, 1, 1] loop = TMR.EdgeLoop([edge1, edge2, edge3, edge4], dirs) face.addEdgeLoop(loop) if use_hole: # Create the second edge loop loop = TMR.EdgeLoop([edge5], [1]) face.addEdgeLoop(loop) verts = [v1, v2, v3, v4, v5] edges = [edge1, edge2, edge3, edge4, edge5] else: verts = [v1, v2, v3, v4] edges = [edge1, edge2, edge3, edge4] faces = [face] # Create the TMRModel geo = TMR.Model(verts, edges, faces) return geo
parts.append(B2.solidBoolean(C2, egads.SUBTRACTION)) # Create the z-arm x0 = [0, 0, 0.25] x1 = [0.25, 0.25, 0.75] B3 = ctx.makeSolidBody(egads.BOX, rdata=[x0, x1]) x0 = [0.125, 0, 0.85] x1 = [0.125, 0.25, 0.85] C3 = ctx.makeSolidBody(egads.CYLINDER, rdata=[x0, x1, r0]) parts.append(B3.solidBoolean(C3, egads.SUBTRACTION)) # Create all of the models geos = [] for p in parts: geos.append(TMR.ConvertEGADSModel(p)) # Create the full list of vertices, edges, faces and volumes verts = [] edges = [] faces = [] vols = [] for geo in geos: verts.extend(geo.getVertices()) edges.extend(geo.getEdges()) faces.extend(geo.getFaces()) vols.extend(geo.getVolumes()) # Set all of the matching faces TMR.setMatchingFaces(geos)