def couple(self): # update porosity and drag self.updatePorosityAndDrag() # receive initial CFD data self.receiveCFDData() # receive initial CFD time self.receiveCFDTime() self.NIter = 0 while self.cfdTime >= 0.0: # solve to catch up CFD time # if CFD Time remains 0 ScTetra is # in stationnary mode... How do we handle this ? if self.cfdTime > 0.0: # attempt to fix the timestep to a reasonable value #itasca.command("set timestep fix {}".format(self.cfdDT/100.0)) self.NIter += 1 print " --- CFD cycle {} --- ".format(self.NIter) itasca.command("solve time {} exact".format(self.cfdDT)) # update porosity and drag self.updatePorosityAndDrag() # send porosiy and drag self.sendPorosityAndDrag() # receive updated CFD data self.receiveCFDData() # receive updated CFD time self.receiveCFDTime() # terminate if cfdtime is negative print "received negative CFD time of {}".format(self.cfdTime) self.terminate()
def show_cracks(): cracks = broken_bonds() output = open("tmp.geom", "w") print >> output, "ITASCA GEOMETRY3D" print >> output, "NODES ; id x y z EXTRA 1 value" for i, c in enumerate(cracks): b1, b2 = c pos = 0.5 * (it.ball.find(b1).pos() + it.ball.find(b2).pos()) print >> output, "{} {} {} {} EXTRA 1 0".format(i + 1, *pos) output.close() it.command("geom delete") it.command("geom import 'tmp.geom' format geometry") return len(cracks)
def show_cracks(geom_name): cracks = broken_bonds() output = open(geom_name, "w") print("ITASCA GEOMETRY3D", file=output) print("NODES ; id x y z EXTRA 1 value", file=output) for i, c in enumerate(cracks): b1, b2 = c pos = 0.5 * (it.ball.find(b1).pos() + it.ball.find(b2).pos()) print("{} {} {} {} EXTRA 1 0".format(i + 1, *pos), file=output) output.close() it.command("geom delete") it.command(f"geom import '{geom_name}' format geometry") return len(cracks)
def draw_fragment(points, faces, i): gname = "tmp{}.geom".format(i) f = open(gname, "w") print("ITASCA GEOMETRY3D", file=f) print("NODES", file=f) for j, p in enumerate(points): x, y, z = p print(j + 1, x, y, z, "EXTRA 1 0", file=f) print("POLYS", file=f) for j, t in enumerate(faces): n0, n1, n2 = t print(j + 1, "NODE", n0 + 1, n1 + 1, n2 + 1, "EXTRA 1 0", file=f) f.close() it.command("geom import {} format geometry".format(gname))
def __init__(self, inistate): """restore the initial PFC state""" itasca.command("restore {}".format(inistate)) itasca.command("set mechanical age 0.0") itasca.command("ball extra 1 [vector(0.0,0.0,0.0)]") itasca.command(""" define set_geometry_extra(gs_id,ex_idx,ex_val) local gs = geom.set.find(gs_id) loop foreach local p geom.poly.list(gs) geom.poly.extra(p,ex_idx) = ex_val endloop end """) pass
class cube_blast(object): def __init__(self): pass def setup(self, material, rise_time, peak_pressure, pressure_decay, hole_radius, case, prefix): it.command(""" model new MODEL LARGE-STRAIN on model res '{savefile}' ball attr damp 0 ball ini disp 0 ball delete range cyl end-1 0 0 -100 end-2 0 0 100 rad {hole_radius} contact prop dp_nratio 0.1 contact prop dp_sratio 0.1 ball prop dp_nratio 0.1 ball prop dp_sratio 0.1 """.format(savefile=material, hole_radius=hole_radius)) self.case = case self.prefix = prefix self.rise_time = rise_time self.peak_pressure = peak_pressure self.pressure_decay = pressure_decay self.rad = float(ba.radius().mean()) self.barea = self.rad**2 * math.pi x, y, z = ba.pos().T annulus = np.sqrt(x**2 + y**2) < (hole_radius + 2 * self.rad) ba.set_extra(1, 1.0 * annulus) # list of ball objects which will carry load self.load_balls = [ it.ball.find(i) for i in ba.ids()[np.nonzero(annulus)[0]] ] # initiall bonds self.initial_bond_list = set(((c.end1().id(), c.end2().id()) for c in \ it.contact.list("mechanical") if (c.model()=='linearpbond' and c.prop("pb_state")==3))) self.starting_time = it.mech_age() self.data = [] it.set_callback("apply_gas_force", 1)
import numpy as np with p2pLinkServer() as cfd_link: cfd_link.start() nodes = cfd_link.read_data() elements = cfd_link.read_data() fluid_density = cfd_link.read_data() fluid_viscosity = cfd_link.read_data() print fluid_density, fluid_viscosity nmin, nmax = np.amin(nodes, axis=0), np.amax(nodes, axis=0) diag = np.linalg.norm(nmin - nmax) dmin, dmax = nmin - 0.1 * diag, nmax + 0.1 * diag print dmin, dmax it.command(""" new domain extent {} {} {} {} {} {} """.format(dmin[0], dmax[0], dmin[1], dmax[1], dmin[2], dmax[2])) ca.create_mesh(nodes, elements) it.command(""" config cfd element cfd ini density {} element cfd ini visc {} cfd porosity poly cfd buoy on cfd relax 1 cfd update call particles.p3dat """.format(fluid_density, fluid_viscosity)) element_volume = ca.volume() dt = 0.005
with p2pLinkServer() as cfd_link: cfd_link.start() nodes = cfd_link.read_data() elements = cfd_link.read_data() fluid_density = cfd_link.read_data() fluid_viscosity = cfd_link.read_data() print fluid_density, fluid_viscosity nmin, nmax = np.amin(nodes,axis=0), np.amax(nodes,axis=0) diag = np.linalg.norm(nmin-nmax) dmin, dmax = nmin -0.1*diag, nmax+0.1*diag print dmin, dmax it.command(""" new domain extent {} {} {} {} {} {} """.format(dmin[0], dmax[0], dmin[1], dmax[1], dmin[2], dmax[2])) ca.create_mesh(nodes, elements) it.command(""" config cfd element cfd ini density {} element cfd ini visc {} cfd porosity poly cfd buoy on cfd relax 1 cfd update call particles.p3dat """.format(fluid_density, fluid_viscosity))
import numpy as np import pylab as plt import math import itasca as it from scipy.constants import inch from load import blast, apply_gas_force, pressure ct = 3e-4 # characteristic time cp = 1e6 # characteristic pressure material = "SS_ParallelBondedFINE-mat.p3sav" hole_radius = 1.5 * inch / 2.0 c = 104 pmult = 1.25 rmult = 2.0 rise_time = ct * rmult peak_pressure = cp * pmult pressure_decay_time = 5 * ct decay = -math.log(0.5) / pressure_decay_time blast.setup(material, rise_time, peak_pressure, decay, hole_radius, c, "fine3") blast.run(rise_time + 1.5e-3) it.command("save basefine3{}_{}.p3sav".format(c, 0)) blast.save()
import itasca as it from pfc_cfd_coupler.pfc_coupler import pfc_coupler coupler = pfc_coupler() it.command(""" restore ../fluidized_bed_2/ini.sav set timestep max 1e-4 set mechanical age 0.0 history add id 3 fish @pressure_drop plot clear plot add ball plot add axes plot add udvector plot add wall transparency 70 plot add hist 3 vs 1 plot add geometry contour """) coupler.max_dt = 0.001 coupler.bandwidth = 0.016 coupler.pressureMeasureCell1 = 12 coupler.pressureMeasureCell2 = 1887 coupler.smallest_size = 0.0016 coupler.solve(0.2) coupler.plotFluidVel() coupler.plotPorosity() coupler.stopSolve() coupler.close() it.command("history write 1,2,3 file 'fluidized_bed_2.txt' truncate")
class cube_blast(object): def __init__(self): pass def setup(self, material, rise_time, peak_pressure, pressure_decay, hole_radius, case, prefix): it.command(""" model new MODEL LARGE-STRAIN on model res '{savefile}' ball attr damp 0 ball ini disp 0 ball delete range cyl end-1 0 0 -100 end-2 0 0 100 rad {hole_radius} contact prop dp_nratio 0.1 contact prop dp_sratio 0.1 ball prop "dp_nratio" 0.1 ball prop "dp_sratio" 0.1 """.format(savefile=material, hole_radius=hole_radius)) inner_radius = it.fish.get("mv_W") / 2.0 assert it.fish.get("mv_W") == it.fish.get("mv_D") outer_radius = inner_radius * 5 thickness = it.fish.get("mv_H") it.command(f""" model config dynamic model domain extent {-1.1*outer_radius} {1.1*outer_radius} {-1.1*outer_radius} {1.1*outer_radius} {-1.1*thickness} {1.1*thickness} condition destroy zone create cylindrical-shell ... point 0 0 {0} {-thickness/2.0} ... point 1 {outer_radius} {0} {-thickness/2.0} ... point 2 0 {0} {thickness/2.0} ... point 3 0 {-outer_radius} {-thickness/2.0} ... point 8 {inner_radius} {0} {-thickness/2.0} ... point 9 0 {-inner_radius} {-thickness/2.0} ... point 10 {inner_radius} {0} {thickness/2.0} ... point 11 0 {-inner_radius} {thickness/2.0} ... size 25 4 25 ratio 1 1 1 zone reflect origin 0 0 0 norm -1 0 0 zone reflect origin 0 0 0 norm 0 -1 0 zone cmodel assign elastic zone property young [pbm_emod+lnm_emod] poisson 0.25 ;zone cmodel assign mohr-coulomb-tension ;zone property young [pbm_emod+lnm_emod] poisson 0.25 cohesion {it.fish.get("pbm_coh_m")} tension {it.fish.get("pbm_ten_m")} friction 50 dilation 0 number-cracks 1 ;zone cmodel assign mohr-coulomb ;zone property young [pbm_emod+lnm_emod] poisson 0.25 cohesion 1e100 tension 1e5 friction 50 dilation 0 ;zone cmodel assign strain-softening ;table 'ConTen_C35' add 0.0000000 .75e6 ... ;0.0000005 1.0000 ... ;0.0000001 1.0000 ... ;0.0002000 1.0000 ;zone property table-tension 'ConTen_C35' young [pbm_emod+lnm_emod] poisson 0.25 cohesion 1e100 friction 40 tension 0.75e6 zone property density [cm_densityVal] wall-zone create name 'dem_boundary' range cylinder end-1 0 0 {-thickness/2.0} end-2 0 0 {thickness/2.0} rad {inner_radius} zone gridpoint fix velocity-z range position-z {thickness/2.0} zone gridpoint fix velocity-z range position-z {-thickness/2.0} zone face apply quiet-normal range cylinder end-1 0 0 {-thickness/2.0} end-2 0 0 {thickness/2.0} rad {.99*outer_radius} not zone face apply velocity-strike 0 range cylinder end-1 0 0 {-thickness/2.0} end-2 0 0 {thickness/2.0} rad {.99*outer_radius} not zone face apply velocity-dip 0 range cylinder end-1 0 0 {-thickness/2.0} end-2 0 0 {thickness/2.0} rad {.99*outer_radius} not contact cmat default model linearpbond property pb_ten 1e100 pb_coh 1e100 method deformability emod {it.fish.get('mv_emod')} kratio 1.0 model clean all contact method bond gap 0 {0.1*it.ball.find(1).radius()} range contact type 'ball-facet' contact property lin_mode 1 pb_ten 1e100 pb_coh 1e100 range contact type 'ball-facet' """) self.case = case self.prefix = prefix self.rise_time = rise_time self.peak_pressure = peak_pressure self.pressure_decay = pressure_decay self.rad = float(ba.radius().mean()) self.barea = self.rad**2 * math.pi x, y, z = ba.pos().T annulus = np.sqrt(x**2 + y**2) < (hole_radius + 2 * self.rad) ba.set_extra(1, 1.0 * annulus) # list of ball objects which will carry load self.load_balls = [ it.ball.find(i) for i in ba.ids()[np.nonzero(annulus)[0]] ] # initiall bonds self.initial_bond_list = set(((c.end1().id(), c.end2().id()) for c in \ it.contact.list("mechanical") if (c.model()=='linearpbond' and c.prop("pb_state")==3))) self.starting_time = it.mech_age() self.data = [] it.set_callback("apply_gas_force", 1)
def run(self, deltat): it.command("solve age {}".format(it.mech_age() + deltat))
def initialize(self, tcp_id='127.0.0.1', tcp_port=3333): # open channel (client mode) self.client = customsocket.CustomSocketClient(tcp_id=tcp_id, tcp_port=tcp_port) self.client.start() # receive mesh from SCTetra # receive number of nodes self.nbNodes = self.client.read_data() print "Number of nodes: ", self.nbNodes # receive node information self.nodes = {} for n in range(0, self.nbNodes): i = self.client.read_data() # node id x = self.client.read_data() # node x y = self.client.read_data() # node y z = self.client.read_data() # node z self.nodes[i] = [x, y, z] #print "coord node {} : {} {} {}".format(n,x,y,z) # receive connectivity information self.nbElem = self.client.read_data() print "Number of elements: ", self.nbElem self.elements_nodes = {} for n in range(0, self.nbElem): i = self.client.read_data() # element ID (should be n) nn = self.client.read_data() # total number of nodes idx = [] for j in range(0, nn): nj = self.client.read_data() # index of node j idx.append(nj) self.elements_nodes[i] = idx # print "connection {} : {}".format(n,ic) # SE: mesh creation takes a while ! self.create_mesh() #SE: find index of polygon closest to a specified position in all sets itasca.command(""" define poly_near(v) local ret = null local d = 1e20 loop foreach local gs geom.set.list local gp = geom.poly.near(gs,v) if gp # null then local dist = math.mag(geom.poly.pos(gp)-v) if dist < d then ret = gp d = dist endif endif endloop poly_near = geom.poly.id(ret) end [gp1 = poly_near(vector(2.0e-2,2.0e-3,3.75e-3))] [gp2 = poly_near(vector(2.0e-2,15.0e-2,3.75e-3))] define pressure_drop pressure_drop = cfd_pressure_drop end history id 1 mechanical age history id 2 @pressure_drop """) self.gpid1 = itasca.fish.get("gp1") - 1 self.gpid2 = itasca.fish.get("gp2") - 1 # UPDATE MESHELEM # receive number of elements self.nbElem = self.client.read_data() print "Number of elements: ", self.nbElem self.elements_geom = {} for n in range(0, self.nbElem): x = self.client.read_data() y = self.client.read_data() z = self.client.read_data() v = self.client.read_data() self.elements_geom[n] = [x, y, z, v] #print "element {} : x = {} y = {} z = {} - vol = {}".format(n,x,y,z,v) #store elements centroids into a numpy array a = numpy.array(self.elements_geom.values()) # remove last column self.elements_pos = numpy.delete(a, -1, 1) # remove first 3 columns self.elements_vol = numpy.delete(a, (0, 1, 2), 1).reshape(-1) # create a cKDTree for lookup self.elements_tree = cKDTree(self.elements_pos)
def create_mesh(self): # write command structure into a temporary file file = open("~tmp.txt", "w") file.write("define create_mesh\n") nlines = 1 for ie in range(0, len(self.elements_nodes)): s = "poly_{}".format(ie + 1) file.write(" gset = geom.set.find({})\n".format(ie + 1)) file.write(" if gset # null then\n") file.write(" geom.set.delete(gset)\n") file.write(" endif\n") file.write(" gset = geom.set.create(\"{}\",{})\n".format( s, ie + 1)) nlines += 5 l = self.elements_nodes[ie] if len(l) == 4: # tetra x0 = self.nodes[l[0]][0] y0 = self.nodes[l[0]][1] z0 = self.nodes[l[0]][2] x1 = self.nodes[l[1]][0] y1 = self.nodes[l[1]][1] z1 = self.nodes[l[1]][2] x2 = self.nodes[l[2]][0] y2 = self.nodes[l[2]][1] z2 = self.nodes[l[2]][2] x3 = self.nodes[l[3]][0] y3 = self.nodes[l[3]][1] z3 = self.nodes[l[3]][2] # face 0 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 1 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 2 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 3 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 elif len(l) == 5: # Pyramid x0 = self.nodes[l[0]][0] y0 = self.nodes[l[0]][1] z0 = self.nodes[l[0]][2] x1 = self.nodes[l[1]][0] y1 = self.nodes[l[1]][1] z1 = self.nodes[l[1]][2] x2 = self.nodes[l[2]][0] y2 = self.nodes[l[2]][1] z2 = self.nodes[l[2]][2] x3 = self.nodes[l[3]][0] y3 = self.nodes[l[3]][1] z3 = self.nodes[l[3]][2] x4 = self.nodes[l[4]][0] y4 = self.nodes[l[4]][1] z4 = self.nodes[l[4]][2] # face 0 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 1 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 2 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 3 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 4 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 elif len(l) == 6: # Prism x0 = self.nodes[l[0]][0] y0 = self.nodes[l[0]][1] z0 = self.nodes[l[0]][2] x1 = self.nodes[l[1]][0] y1 = self.nodes[l[1]][1] z1 = self.nodes[l[1]][2] x2 = self.nodes[l[2]][0] y2 = self.nodes[l[2]][1] z2 = self.nodes[l[2]][2] x3 = self.nodes[l[3]][0] y3 = self.nodes[l[3]][1] z3 = self.nodes[l[3]][2] x4 = self.nodes[l[4]][0] y4 = self.nodes[l[4]][1] z4 = self.nodes[l[4]][2] x5 = self.nodes[l[5]][0] y5 = self.nodes[l[5]][1] z5 = self.nodes[l[5]][2] # face 0 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 1 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x5, y5, z5)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 2 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x5, y5, z5)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 3 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 # face 4 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x5, y5, z5)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write("geom.poly.close(gset,gp)\n") nlines += 5 elif len(l) == 8: # Prism x0 = self.nodes[l[0]][0] y0 = self.nodes[l[0]][1] z0 = self.nodes[l[0]][2] x1 = self.nodes[l[1]][0] y1 = self.nodes[l[1]][1] z1 = self.nodes[l[1]][2] x2 = self.nodes[l[2]][0] y2 = self.nodes[l[2]][1] z2 = self.nodes[l[2]][2] x3 = self.nodes[l[3]][0] y3 = self.nodes[l[3]][1] z3 = self.nodes[l[3]][2] x4 = self.nodes[l[4]][0] y4 = self.nodes[l[4]][1] z4 = self.nodes[l[4]][2] x5 = self.nodes[l[5]][0] y5 = self.nodes[l[5]][1] z5 = self.nodes[l[5]][2] x6 = self.nodes[l[6]][0] y6 = self.nodes[l[6]][1] z6 = self.nodes[l[6]][2] x7 = self.nodes[l[7]][0] y7 = self.nodes[l[7]][1] z7 = self.nodes[l[7]][2] # face 0 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x5, y5, z5)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 1 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x5, y5, z5)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x6, y6, z6)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 2 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x6, y6, z6)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x7, y7, z7)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 3 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x7, y7, z7)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 4 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x0, y0, z0)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x1, y1, z1)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x2, y2, z2)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x3, y3, z3)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 # face 5 file.write("gp = geom.poly.create(gset)\n") file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x7, y7, z7)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x6, y6, z6)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x5, y5, z5)) file.write( "geom.poly.add.node(gset,gp,vector({},{},{}))\n".format( x4, y4, z4)) file.write("geom.poly.close(gset,gp)\n") nlines += 6 else: print "incorrect shape !" file.write("end\n") file.write("@create_mesh") nlines += 2 file.close() itasca.command(""" define read_tmp local a = array.create({nl}) file.open("~tmp.txt",0,1) file.read(a,{nl}) file.close() array.command(a) end @read_tmp """.format(nl=nlines)) os.remove("~tmp.txt")
it.command(""" set timestep max 1e-5 set deterministic on set random 1 ball generate rad 0.00075 number 2160 box 0 0.04 0 0.06 0 0.0075 wall generate box 0 0.04 0 0.2 0 0.0075 ball ini dens 2000 cmat default model linear property kn 5000 ks 5000 fric 0.15 dp_nratio 0.1 set gravity 0 -9.81 0 def ball_height local max = 0 loop foreach local b ball.list if ball.pos.y(b) > max then max = ball.pos.y(b) endif endloop ball_height = max end define pressure_drop pressure_drop = cfd_pressure_drop end def fluid_time global fluid_time = mech.age end history add id 1 fish @fluid_time history add id 2 fish @ball_height cy 20000 ball ini damp 0.7 cy 20000 save ini.sav """)
def update_geom_PoroAndDrag(self): #update geometry set extra itasca.command("set echo off") for ie in range(0, self.nbElem): itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 1, float(self.elements_porosity[ie]))) itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 2, float(self.elements_drag[ie][0]))) itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 3, float(self.elements_drag[ie][1]))) itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 4, float(self.elements_drag[ie][2]))) itasca.command("set echo on")
def update_geom_PressureAndVel(self): itasca.command("set echo off") for ie in range(0, self.nbElem): itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 5, float(self.elements_field[ie][0]))) # x-vel itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 6, float(self.elements_field[ie][1]))) # y-vel itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 7, float(self.elements_field[ie][2]))) # z-vel itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 8, float(self.elements_field[ie][3]))) # pressure itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 9, float(self.elements_field[ie][4]))) # dpx itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 10, float(self.elements_field[ie][5]))) # dpy itasca.command("@set_geometry_extra({},{},{})".format( ie + 1, 11, float(self.elements_field[ie][6]))) # dpz itasca.command("set echo on")
import itasca as it from pfc_cfd_coupler.pfc_coupler import pfc_coupler coupler = pfc_coupler() it.command("call ../fluidized_bed_3/make_ini.p3dat") coupler.max_dt = 0.001 coupler.smallest_size = 0.00095 coupler.bandwidth = 2 * coupler.smallest_size coupler.initialize() coupler.solve(4.0) coupler.plotFluidVel() coupler.plotPorosity() coupler.stopSolve() coupler.close() it.command("history write 1,2 file 'fluidized_bed_3.txt' truncate")
from IPython import get_ipython get_ipython().magic('reset -sf') import itasca as it it.command("python-reset-state false") import numpy as np import pylab as plt import math from scipy.constants import inch from importlib import reload import coupled_load coupled_load = reload(coupled_load) blast, apply_gas_force, pressure = coupled_load.blast, coupled_load.apply_gas_force, coupled_load.pressure ct = 3e-4 # characteristic time cp = 1e6 # characteristic pressure material = "disc-mat.p3sav" hole_radius = 1.5 * inch / 2.0 prefix = "evis" c = 0 for pmult in [0.75, 1.0, 1.25, 1.5, 2.0]: for rmult in [0.1, 0.5, 1, 2, 10]: rise_time = ct * rmult peak_pressure = cp * pmult pressure_decay_time = 5 * ct decay = -math.log(0.5) / pressure_decay_time blast.setup(material, rise_time, peak_pressure, decay, hole_radius, c,
import itasca as it from pfc_cfd_coupler.pfc_coupler import pfc_coupler coupler = pfc_coupler() it.command(""" ball create rad 0.005 x 0.5 y 0.5 z 0.5 ball ini dens 2500 ball prop kn 1e2 ks 1e2 fric 0.25 set gravity 0 0 -9.81 def fluid_time global fluid_time = mech.age end def appforce global appforce = ball.force.app.z(ball.find(1)) end history add id 1 fish @fluid_time ball history id 2 zvelocity id 1 ball history id 3 zunbalforce id 1 history add id 4 fish @appforce plot clear plot add hist 2 vs 1 plot add ball shape arrow plot add axes plot add domain plot add udvector """) coupler.dt = 0.005 coupler.bandwidth = 0.3 coupler.solve(100) coupler.plotFluidUnitVel()
from IPython import get_ipython; get_ipython().magic('reset -sf') import itasca as it it.command("python-reset-state false") import numpy as np it.command('model restore "disc-mat.p3sav"') inner_radius = it.fish.get("mv_W")/2.0 assert it.fish.get("mv_W") == it.fish.get("mv_D") outer_radius = inner_radius*3 thickness = it.fish.get("mv_H") it.command(f""" model config dynamic model domain extent {-1.1*outer_radius} {1.1*outer_radius} {-1.1*outer_radius} {1.1*outer_radius} {-1.1*thickness} {1.1*thickness} condition destroy zone create cylindrical-shell ... point 0 0 {0} {-thickness/2.0} ... point 1 {outer_radius} {0} {-thickness/2.0} ... point 2 0 {0} {thickness/2.0} ... point 3 0 {-outer_radius} {-thickness/2.0} ... point 8 {inner_radius} {0} {-thickness/2.0} ... point 9 0 {-inner_radius} {-thickness/2.0} ... point 10 {inner_radius} {0} {thickness/2.0} ... point 11 0 {-inner_radius} {thickness/2.0} ... size 15 4 15 ratio 1.1 1.1 1 zone reflect origin 0 0 0 norm -1 0 0 zone reflect origin 0 0 0 norm 0 -1 0 zone cmodel assign elastic zone property young [pbm_emod+lnm_emod] poisson 0.25
]) if (edge_lengths < 4 * max_rad).all(): keep.append(nl) face_hash = defaultdict(int) for tet in keep: # indices into point list for n0, n1, n2 in indices: face = [tet[n0], tet[n1], tet[n2]] face.sort() face_hash[tuple(face)] += 1 outside_faces = [k for k, v in face_hash.items() if v == 1] uniques = list(set(itertools.chain(*outside_faces))) pmap = {v: i for i, v in enumerate(uniques)} face_points = points[uniques] centroid = np.sum(face_points, axis=0) / len(face_points) if not explode_xyz: centroid[2] = 0 offset = centroid / np.linalg.norm(centroid) * explode face_points += offset draw_fragment(face_points, [[pmap[t[j]] for j in range(3)] for t in outside_faces], fid) if __name__ == '__main__': #sf = "ablast{}.p3sav".format(13) #base3d_5.p3sav #sf = "basefine103_0.p3sav" #it.command("res {}".format(sf)) it.command("geometry delete") mesh_fragments(explode=0.0, explode_xyz=True)
with p2pLinkServer() as cfd_link: cfd_link.start() nodes = cfd_link.read_data() elements = cfd_link.read_data() fluid_density = cfd_link.read_data() fluid_viscosity = cfd_link.read_data() print fluid_density, fluid_viscosity nmin, nmax = np.amin(nodes, axis=0), np.amax(nodes, axis=0) diag = np.linalg.norm(nmin - nmax) dmin, dmax = nmin - 0.1 * diag, nmax + 0.1 * diag print dmin, dmax it.command(""" new domain extent {} {} {} {} {} {} """.format(dmin[0], dmax[0], dmin[1], dmax[1], dmin[2], dmax[2])) ca.create_mesh(nodes, elements) it.command(""" config cfd set timestep max 1e-5 element cfd ini density {} element cfd ini visc {} cfd porosity poly cfd buoy on ball create rad 0.005 x 0.5 y 0.5 z 0.5 ball ini dens 2500 ball prop kn 1e2 ks 1e2 fric 0.25 set gravity 0 0 -9.81 def fluid_time global fluid_time = mech.age
import itasca as it from itasca import cfdarray as ca from itasca.util import p2pLinkServer import numpy as np cfd_link = p2pLinkServer() cfd_link.start() nodes = cfd_link.read_data() elements = cfd_link.read_data() fluid_density = cfd_link.read_data() fluid_viscosity = cfd_link.read_data() it.command("call ../fluidized_bed_4/make_ini.p3dat") ca.create_mesh(nodes, elements) it.command(""" config cfd element cfd ini density {} element cfd ini visc {} cfd porosity poly cfd buoy on cfd interval 0 element cfd history id 3 zvelocity id 1 plot add hist 2 vs 1 """.format(fluid_density, fluid_viscosity)) element_volume = ca.volume() oldu = ca.velocity() old_force = (ca.drag().T/element_volume).T/fluid_density
with p2pLinkServer() as cfd_link: cfd_link.start() nodes = cfd_link.read_data() elements = cfd_link.read_data() fluid_density = cfd_link.read_data() fluid_viscosity = cfd_link.read_data() print fluid_density, fluid_viscosity nmin, nmax = np.amin(nodes,axis=0), np.amax(nodes,axis=0) diag = np.linalg.norm(nmin-nmax) dmin, dmax = nmin -0.1*diag, nmax+0.1*diag print dmin, dmax it.command(""" new domain extent {} {} {} {} {} {} """.format(dmin[0], dmax[0], dmin[1], dmax[1], dmin[2], dmax[2])) ca.create_mesh(nodes, elements) it.command(""" config cfd set timestep max 1e-5 element cfd ini density {} element cfd ini visc {} cfd porosity poly cfd buoy on ball create rad 0.005 x 0.5 y 0.5 z 0.5 ball ini dens 2500 ball prop kn 1e2 ks 1e2 fric 0.25 set gravity 0 0 -9.81 def fluid_time
import itasca as it from pfc_cfd_coupler.pfc_coupler import pfc_coupler coupler = pfc_coupler() it.command("call ../porous/particles.p3dat") coupler.max_dt = 0.005 coupler.bandwidth = 0.02 coupler.smallest_size = 0.01 coupler.initialize() time = 0.0 while time < 0.1: dt = coupler.max_dt coupler.solve(dt) it.fish.set("cfd_vel", coupler.elements_vel[0][1]) time += dt coupler.plotFluidVel() coupler.plotPorosity() coupler.stopSolve() coupler.close()
cfd_link = p2pLinkServer() cfd_link.start() nodes = cfd_link.read_data() elements = cfd_link.read_data() fluid_density = cfd_link.read_data() fluid_viscosity = cfd_link.read_data() print fluid_density, fluid_viscosity nmin, nmax = np.amin(nodes, axis=0), np.amax(nodes, axis=0) diag = np.linalg.norm(nmin - nmax) dmin, dmax = nmin - 0.1 * diag, nmax + 0.1 * diag print dmin, dmax it.command(""" new domain extent {} {} {} {} {} {} """.format(dmin[0], dmax[0], dmin[1], dmax[1], dmin[2], dmax[2])) ca.create_mesh(nodes, elements) it.command(""" config cfd set timestep max 1e-5 element cfd ini density {} element cfd ini visc {} ;cfd porosity poly cfd buoy on ball create rad 0.005 x 0.5 y 0.5 z 0.5 ball ini dens 2500 ball prop kn 1e2 ks 1e2 fric 0.25 set gravity 0 0 -9.81 def fluid_time global fluid_time = mech.age