def isItalic(im): im_s = transform(im, alpha*np.pi/180) p, p_s = project(im), project(im_s) width = 1 fig = plt.figure() a=fig.add_subplot(1,4,1) plt.bar(range(len(p)), p, width, color="blue") a.set_title('Original') a=fig.add_subplot(1,4,2) plt.imshow(im) a=fig.add_subplot(1,4,3) plt.bar(range(len(p)), p_s, width, color="blue") a.set_title('Slanted') a=fig.add_subplot(1,4,4) plt.imshow(im_s) plt.show() b,l,t,r = fit_contours(im) b_s, l_s, t_s, r_s = fit_contours(im_s) width = -l + r + 1 width_s = -l_s + r_s +1 print width, width_s if width < width_s: return False elif width > width_s: return True else: # print "Width unchanged" p, p_s = project(im), project(im_s) if max(p_s) > max(p): return False return True
def write_output(self, pb=None, writemesh=False, N=1, t=0): if writemesh: if self.write_results_every > 0: self.resultsfiles = {} for res in self.results_to_write: outfile = XDMFFile( self.comm, self.output_path + '/results_' + pb.simname + '_' + res + '.xdmf', 'w') outfile.write_mesh(self.mesh) self.resultsfiles[res] = outfile return else: # write results every write_results_every steps if self.write_results_every > 0 and N % self.write_results_every == 0: # save solution to XDMF format for res in self.results_to_write: if res == 'velocity': self.resultsfiles[res].write_function(pb.v, t) elif res == 'acceleration': # passed in a is not a function but form, so we have to project a_proj = project(pb.acc, pb.V_v, pb.dx_, nm="Acceleration") self.resultsfiles[res].write_function(a_proj, t) elif res == 'pressure': self.resultsfiles[res].write_function(pb.p, t) elif res == 'cauchystress': stressfuncs = [] for n in range(pb.num_domains): stressfuncs.append(pb.ma[n].sigma(pb.v, pb.p)) cauchystress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="CauchyStress") self.resultsfiles[res].write_function(cauchystress, t) elif res == 'reynolds': reynolds = project(re, pb.Vd_scalar, pb.dx_, nm="Reynolds") self.resultsfiles[res].write_function(reynolds, t) else: raise NameError( "Unknown output to write for fluid mechanics!")
def errornorm(u, uh, norm_type="L2", degree_rise=3, mesh=None): """Compute the error :math:`e = u - u_h` in the specified norm. :arg u: a :class:`.Function` containing an "exact" solution :arg uh: a :class:`.Function` containing the approximate solution :arg norm_type: the type of norm to compute, see :func:`.norm` for details of supported norm types. :arg degree_rise: increase in polynomial degree to use as the approximation space for computing the error. :arg mesh: an optional mesh on which to compute the error norm (currently ignored). This function works by :func:`.project`\ing ``u`` and ``uh`` into a space of degree ``degree_rise`` higher than the degree of ``uh`` and computing the error there. """ urank = len(u.shape()) uhrank = len(uh.shape()) rank = urank if urank != uhrank: raise RuntimeError("Mismatching rank between u and uh") degree = uh.function_space().ufl_element().degree() if isinstance(degree, tuple): degree = max(degree) + degree_rise else: degree += degree_rise # The exact solution might be an expression, in which case this test is irrelevant. if isinstance(u, function.Function): degree_u = u.function_space().ufl_element().degree() if degree > degree_u: warning("Degree of exact solution less than approximation degree") mesh = uh.function_space().mesh() if rank == 0: V = functionspace.FunctionSpace(mesh, 'DG', degree) elif rank == 1: V = functionspace.VectorFunctionSpace(mesh, 'DG', degree, dim=u.shape()[0]) else: raise RuntimeError("Don't know how to compute error norm for tensor valued functions") u_ = projection.project(u, V) uh_ = projection.project(uh, V) uh_ -= u_ return norm(uh_, norm_type=norm_type, mesh=mesh)
def evaluate_active_stress_ode(self, t): # take care of Frank-Starling law (fiber stretch-dependent contractility) if self.have_frank_starling: amp_old_, na = [], 0 for n in range(self.num_domains): if self.mat_active_stress[n] and self.actstress[na].frankstarling: # old fiber stretch (needed for Frank-Starling law) if self.mat_growth[n]: lam_fib_old = self.ma[n].fibstretch_e(self.ki.C(self.u_old), self.theta_old, self.fib_func[0]) else: lam_fib_old = self.ki.fibstretch(self.u_old, self.fib_func[0]) amp_old_.append(self.actstress[na].amp(t-self.dt, lam_fib_old, self.amp_old)) else: amp_old_.append(as_ufl(0)) amp_old_proj = project(amp_old_, self.Vd_scalar, self.dx_) self.amp_old.vector.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) self.amp_old.interpolate(amp_old_proj) tau_a_, na = [], 0 for n in range(self.num_domains): if self.mat_active_stress[n]: # fiber stretch (needed for Frank-Starling law) if self.actstress[na].frankstarling: if self.mat_growth[n]: lam_fib = self.ma[n].fibstretch_e(self.ki.C(self.u), self.theta, self.fib_func[0]) else: lam_fib = self.ki.fibstretch(self.u, self.fib_func[0]) else: lam_fib = as_ufl(1) tau_a_.append(self.actstress[na].tau_act(self.tau_a_old, t, self.dt, lam_fib, self.amp_old)) na+=1 else: tau_a_.append(as_ufl(0)) # project and interpolate to quadrature function space tau_a_proj = project(tau_a_, self.Vd_scalar, self.dx_) self.tau_a.vector.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) self.tau_a.interpolate(tau_a_proj)
def readin_fibers(self, fibarray, V_fib, dx_): # V_fib_input is function space the fiber vector is defined on (only CG1 or DG0 supported, add further depending on your input...) if list(self.fiber_data.keys())[0] == 'nodal': V_fib_input = VectorFunctionSpace(self.mesh, ("CG", 1)) elif list(self.fiber_data.keys())[0] == 'elemental': V_fib_input = VectorFunctionSpace(self.mesh, ("DG", 0)) else: raise AttributeError("Specify 'nodal' or 'elemental' for the fiber data input!") fib_func = [] fib_func_input = [] si = 0 for s in fibarray: fib_func_input.append(Function(V_fib_input, name='Fiber'+str(si+1)+'_input')) self.readfunction(fib_func_input[si], V_fib_input, list(self.fiber_data.values())[0][si], normalize=True) # project to output fiber function space ff = project(fib_func_input[si], V_fib, dx_, bcs=[], nm='fib_'+s+'') # assure that projected field still has unit length (not always necessarily the case) fib_func.append(ff / sqrt(dot(ff,ff))) ## write input fiber field for checking... #outfile = XDMFFile(self.comm, self.output_path+'/fiber'+str(si+1)+'_input.xdmf', 'w') #outfile.write_mesh(self.mesh) #outfile.write_function(fib_func_input[si]) si+=1 return fib_func
def selfInterior(surf, s, LorY, param, ind0, timing, kernel): # print 'SELF INTERIOR, surface: %i'%s K_diag = 2 * pi V_diag = 0 IorE = 1 K_lyr, V_lyr = project(surf.XinK, surf.XinV, LorY, surf, surf, K_diag, V_diag, IorE, s, param, ind0, timing, kernel) v = K_lyr - V_lyr return v
def selfExterior(surf, s, LorY, param, ind0, timing, kernel): # print 'SELF EXTERIOR, surface: %i, E_hat: %f'%(s, surf.E_hat) K_diag = -2 * pi V_diag = 0. IorE = 2 K_lyr, V_lyr = project(surf.XinK, surf.XinV, LorY, surf, surf, K_diag, V_diag, IorE, s, param, ind0, timing, kernel) v = -K_lyr + surf.E_hat * V_lyr return v, K_lyr, V_lyr
def project(self, b, *args, **kwargs): """Project ``b`` onto ``self``. ``b`` must be a :class:`Function` or an :class:`Expression`. This is equivalent to ``project(b, self)``. Any of the additional arguments to :func:`~firedrake.projection.project` may also be passed, and they will have their usual effect. """ return projection.project(b, self, *args, **kwargs)
def nonselfExterior(surf, src, tar, LorY, param, ind0, timing, kernel): # print 'NONSELF EXTERIOR, source: %i, target: %i, E_hat: %f'%(src,tar, surf[src].E_hat) K_diag = 0 V_diag = 0 IorE = 1 K_lyr, V_lyr = project(surf[src].XinK, surf[src].XinV, LorY, surf[src], surf[tar], K_diag, V_diag, IorE, src, param, ind0, timing, kernel) v = -K_lyr + surf[src].E_hat*V_lyr return v
def nonselfInterior(surf, src, tar, LorY, param, ind0, timing, kernel): # print 'NONSELF INTERIOR, source: %i, target: %i'%(src,tar) K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf[src].XinK, surf[src].XinV, LorY, surf[src], surf[tar], K_diag, V_diag, IorE, src, param, ind0, timing, kernel) v = K_lyr - V_lyr return v
def selfExterior(surf, s, LorY, param, ind0, timing, kernel): # print 'SELF EXTERIOR, surface: %i, E_hat: %f'%(s, surf.E_hat) K_diag = -2*pi V_diag = 0. IorE = 2 K_lyr, V_lyr = project(surf.XinK, surf.XinV, LorY, surf, surf, K_diag, V_diag, IorE, s, param, ind0, timing, kernel) v = -K_lyr + surf.E_hat*V_lyr return v, K_lyr, V_lyr
def selfInterior(surf, s, LorY, param, ind0, timing, kernel): # print 'SELF INTERIOR, surface: %i'%s K_diag = 2*pi V_diag = 0 IorE = 1 K_lyr, V_lyr = project(surf.XinK, surf.XinV, LorY, surf, surf, K_diag, V_diag, IorE, s, param, ind0, timing, kernel) v = K_lyr - V_lyr return v
def nonselfExterior(surf, src, tar, LorY, param, ind0, timing, kernel): # print 'NONSELF EXTERIOR, source: %i, target: %i, E_hat: %f'%(src,tar, surf[src].E_hat) K_diag = 0 V_diag = 0 IorE = 1 K_lyr, V_lyr = project(surf[src].XinK, surf[src].XinV, LorY, surf[src], surf[tar], K_diag, V_diag, IorE, src, param, ind0, timing, kernel) v = -K_lyr + surf[src].E_hat * V_lyr return v
def taylor_test_expression(exp, V): """ Performs a Taylor test of an Expression with dependencies. exp: The expression to test V: A suitable function space on which the expression will be projected. Warning: This function resets the adjoint tape! """ adjglobals.adj_reset() # Annotate test model s = projection.project(exp, V, annotate=True) mesh = V.mesh() Jform = s**2*backend.dx + exp*backend.dx(domain=mesh) J = functional.Functional(Jform) J0 = backend.assemble(Jform) deps = exp.dependencies() controls = [Control(c) for c in deps] dJd0 = drivers.compute_gradient(J, controls, forget=False) for i in range(len(controls)): def Jfunc(new_val): dep = exp.dependencies()[i] # Remember the old dependency value for later old_val = float(dep) # Compute the functional value dep.assign(new_val) s = projection.project(exp, V, annotate=False) out = backend.assemble(s**2*backend.dx + exp*backend.dx(domain=mesh)) # Restore the old dependency value dep.assign(old_val) return out #HJ = hessian(J, controls[i], warn=False) #minconv = taylor_test(Jfunc, controls[i], J0, dJd0[i], HJm=HJ) minconv = taylor_test(Jfunc, controls[i], J0, dJd0[i]) if math.isnan(minconv): warning("Convergence order is not a number. Assuming that you \ have a linear or constant constraint dependency (e.g. check that the Taylor \ remainder are all 0).") else: if not minconv > 1.9: raise Exception, "The Taylor test failed when checking the \ derivative with respect to the %i'th dependency." % (i+1) adjglobals.adj_reset()
def segment(line): projection = project(line) SPACES = [] space = [] for i, p in enumerate(projection): if i != len(projection)-1: if p == 0: space.append(i) else: if len(space) > 0: SPACES.append((space[0], space[-1], len(space))) space = [] else: if p == 0: space.append(i) if len(space) > 0: SPACES.append((space[0], space[-1], len(space))) x = np.ndarray((len(SPACES), 2), dtype = np.float) # print x for i in range(len(SPACES)): x[i] = [SPACES[i][-1],0] print x kmeans = KMeans(n_clusters=2, random_state=0).fit(x) cluster = kmeans.labels_ space_chars = [] space_words = [] for i, c in enumerate(cluster): if c == 0: space_chars.append(SPACES[i][-1]) else: space_words.append(SPACES[i][-1]) if (float)(sum(space_chars))/len(space_chars) > (float)(sum(space_words))/len(space_words): cluster = [1 - c for c in cluster] boundary = [] for i in range(len(SPACES)): if cluster[i] == 1: boundary.append((SPACES[i][1]+SPACES[i][0])/2) img = line.copy() for b in boundary: for i in range(img.shape[0]): img[i][b] = 0 cv2.imshow('segmentation', img) cv2.waitKey() # width = 1 # fig = plt.figure() # a=fig.add_subplot(1,2,1) # plt.bar(range(len(projection)), projection, width, color="blue") # a.set_title('Vertical Projection') # a=fig.add_subplot(1,2,2) # plt.imshow(img) # a.set_title('Segmentation') # plt.show() print boundary
def prestress_update(self, u_, V, dx_, u_pre=None): F_hist_proj = project(self.F(u_), V, dx_) self.F_hist.interpolate(F_hist_proj) # for springs if u_pre is not None: u_pre.vector.axpy(1.0, u_.vector) u_pre.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) u_.vector.set(0.0) u_.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
def run(): radius = 10 # plt.ion() # fig = plt.figure() nodes = NodeSet('nodes.txt') edges = EdgeSet('edges.txt') seeds = Seeds('seeds.txt') start = (-3120000,-5220800) seeds.push(start) while (seeds): seed = seeds.pop() origin = [v * 1e-5 for v in seed] for direction in xrange(0, 360, 90): destination = project(origin, direction, radius) road = getDirections(origin, destination) if not road or not len(road) > 4: continue road = road[1:-1] # endpoints can be interpolated by directions api - this is not desireable endNode = road[-1] if not nodes.contains(endNode): seeds.push(endNode) # fig.gca().plot(endNode[1], endNode[0], 'o') for n in xrange(len(road)-1): firstnode = road[n] nextnode = road[n+1] ##################################### ## nodes are not being added properly by "nodes.addNode(node)" firstindex = nodes.addNode(firstnode) nextindex = nodes.addNode(nextnode) if firstindex < 0: continue seeds.purge(firstnode) edge = tuple(sorted([firstindex, nextindex])) edges.addEdge(edge)
def Jfunc(new_val): dep = exp.dependencies()[i] # Remember the old dependency value for later old_val = float(dep) # Compute the functional value dep.assign(new_val) s = projection.project(exp, V, annotate=False) out = backend.assemble(s**2*backend.dx + exp*backend.dx(domain=mesh)) # Restore the old dependency value dep.assign(old_val) return out
def set_homeostatic_threshold(self, t): # time is absolute time (should only be set in first cycle) eps = 1.0e-14 if t >= self.pb.t_gandr_setpoint - eps and t < self.pb.t_gandr_setpoint + self.pb.pbs.dt - eps: if self.pb.comm.rank == 0: print('Set homeostatic growth thresholds...') sys.stdout.flush() time.sleep(1) growth_thresolds = [] for n in range(self.pb.pbs.num_domains): if self.pb.pbs.mat_growth[n]: growth_settrig = self.pb.pbs.constitutive_models[ 'MAT' + str(n + 1) + '']['growth']['growth_settrig'] if growth_settrig == 'fibstretch': growth_thresolds.append(self.pb.pbs.ma[n].fibstretch_e( self.pb.pbs.ki.C(self.pb.pbs.u), self.pb.pbs.theta, self.pb.pbs.fib_func[0])) elif growth_settrig == 'volstress': growth_thresolds.append( tr(self.pb.pbs.ma[n].M_e( self.pb.pbs.u, self.pb.pbs.p, self.pb.pbs.ki.C(self.pb.pbs.u), ivar=self.pb.pbs.internalvars))) else: raise NameError( "Unknown growth trigger to be set as homeostatic threshold!" ) else: growth_thresolds.append(as_ufl(0)) growth_thres_proj = project(growth_thresolds, self.pb.pbs.Vd_scalar, self.pb.pbs.dx_) self.pb.pbs.growth_thres.vector.ghostUpdate( addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) self.pb.pbs.growth_thres.interpolate(growth_thres_proj)
def function_arg(self, g): '''Set the value of this boundary condition.''' if isinstance(g, function.Function) and g.function_space() != self._function_space: raise RuntimeError("%r is defined on incompatible FunctionSpace!" % g) if not isinstance(g, expression.Expression): try: # Bare constant? as_ufl(g) except UFLException: try: # List of bare constants? Convert to Expression g = expression.to_expression(g) except: raise ValueError("%r is not a valid DirichletBC expression" % (g,)) if isinstance(g, expression.Expression): self._expression_state = g._state try: g = function.Function(self._function_space).interpolate(g) # Not a point evaluation space, need to project onto V except NotImplementedError: g = projection.project(g, self._function_space) self._function_arg = g self._currently_zeroed = False
# This code is entirely sequential. # # Only the projection of one degree of freedom supported in this version. # # Notes: This code is not generating the exact same result than the one # provided in pres.fine although it is close. For tol around 1.2 it gets the # same number of points projected, so it is actually catching all the points as # the other code does. from projection import readBinaryMatrix, project # Parameters tol = 0.0 nn = 25014 nn2 = 110618 ne = 123911 ne2 = 570520 # Load data print('Loading data...') mien_coarse = readBinaryMatrix('mien.coarse', ne, 4, int, swapped=True) xyz_coarse = readBinaryMatrix('mxyz.coarse', nn, 3, float, swapped=True) xyz_fine = readBinaryMatrix('mxyz.fine', nn2, 3, float, swapped=True) pres_coarse = readBinaryMatrix('pres.coarse', nn, 1, swapped=True).flatten() mien_coarse -= 1 # Index in python starts in 0 print('Data loaded!') # Projection print('Projecting...') pres_fine = project(mien_coarse, xyz_coarse, xyz_fine, pres_coarse, tol)
def evaluateQuery(query, metadataDict): for stmnt_unformated in sqlparse.parse(query): statement = sqlparse.parse(sqlparse.format(str(stmnt_unformated)))[0] query_tokens = [] for x in statement.tokens: if re.match('([\s]+)', str(x)): continue else: query_tokens.append(str(x)) #print query_tokens distinct_flag = 0 distinct_flag2 = 0 if str(query_tokens[1]).lower() == "distinct": distinct_flag = 1 elif "distinct(" in query: distinct_flag2 = 1 #print distinct_flag2 colNames = query_tokens[1 + distinct_flag].split(",") #print colNames tableNames = query_tokens[3 + distinct_flag].split(",") #print tableNames #Error Handling error_handling(query, colNames, tableNames) #Checking for aggregate function func = ["min", "max", "count", "sum", "avg"] if any(x in query for x in func): aggregate(colNames[0], tableNames[0]) return #reading table data from file temp_table_data = [] table_data = [] cross = [] for t in tableNames: f = open(t + ".csv", 'r') temp_table_data = [line.replace('"', '').strip() for line in f] if len(table_data) == 0: table_data = temp_table_data else: for y in temp_table_data: for z in table_data: cross.append(z + "," + y) table_data = cross cross = [] #print table_data #Checking for Where Condition index = 4 + distinct_flag if len(query_tokens) > index: whereCond = "" whereCond = query_tokens[index][6:] #print whereCond table_data = whereEvaluate(whereCond, tableNames, table_data) #Projection table_data = project(colNames, tableNames, table_data) if distinct_flag == 1 or distinct_flag2 == 1: table_data = [table_data[0], distinct(table_data[1])] # for x in table_data: # print table_data #Printing Output print "Output:" header = "" flag = 0 for i in table_data[0]: if flag == 0: header += str(i) flag = 1 else: header = header + "," + str(i) print header for x in table_data[1]: flag = 0 valstr = "" if isinstance(x, list): for y in x: #print y if flag == 0: valstr = valstr + str(y) flag = 1 else: valstr = valstr + "," + str(y) #print valstr else: if flag == 0: valstr = valstr + str(x) flag = 1 else: valstr = valstr + "," + str(x) print valstr
def __init__(self, io_params, time_params, fem_params, constitutive_models, bc_dict, time_curves, io, comm=None): problem_base.__init__(self, io_params, time_params, comm) self.problem_physics = 'solid' self.simname = io_params['simname'] self.io = io # number of distinct domains (each one has to be assigned a own material model) self.num_domains = len(constitutive_models) self.order_disp = fem_params['order_disp'] try: self.order_pres = fem_params['order_pres'] except: self.order_pres = 1 self.quad_degree = fem_params['quad_degree'] self.incompressible_2field = fem_params['incompressible_2field'] self.fem_params = fem_params self.constitutive_models = constitutive_models # collect domain data self.dx_, self.rho0, self.rayleigh, self.eta_m, self.eta_k = [], [], [False]*self.num_domains, [], [] for n in range(self.num_domains): # integration domains self.dx_.append(dx(subdomain_data=self.io.mt_d, subdomain_id=n+1, metadata={'quadrature_degree': self.quad_degree})) # data for inertial and viscous forces: density and damping if self.timint != 'static': self.rho0.append(constitutive_models['MAT'+str(n+1)+'']['inertia']['rho0']) if 'rayleigh_damping' in constitutive_models['MAT'+str(n+1)+''].keys(): self.rayleigh[n] = True self.eta_m.append(constitutive_models['MAT'+str(n+1)+'']['rayleigh_damping']['eta_m']) self.eta_k.append(constitutive_models['MAT'+str(n+1)+'']['rayleigh_damping']['eta_k']) try: self.prestress_initial = fem_params['prestress_initial'] except: self.prestress_initial = False # type of discontinuous function spaces if str(self.io.mesh.ufl_cell()) == 'tetrahedron' or str(self.io.mesh.ufl_cell()) == 'triangle3D': dg_type = "DG" if (self.order_disp > 1 or self.order_pres > 1) and self.quad_degree < 3: raise ValueError("Use at least a quadrature degree of 3 or more for higher-order meshes!") elif str(self.io.mesh.ufl_cell()) == 'hexahedron' or str(self.io.mesh.ufl_cell()) == 'quadrilateral3D': dg_type = "DQ" if (self.order_disp > 1 or self.order_pres > 1) and self.quad_degree < 5: raise ValueError("Use at least a quadrature degree of 5 or more for higher-order meshes!") else: raise NameError("Unknown cell/element type!") # create finite element objects for u and p P_u = VectorElement("CG", self.io.mesh.ufl_cell(), self.order_disp) P_p = FiniteElement("CG", self.io.mesh.ufl_cell(), self.order_pres) # function spaces for u and p self.V_u = FunctionSpace(self.io.mesh, P_u) self.V_p = FunctionSpace(self.io.mesh, P_p) # Quadrature tensor, vector, and scalar elements Q_tensor = TensorElement("Quadrature", self.io.mesh.ufl_cell(), degree=1, quad_scheme="default") Q_vector = VectorElement("Quadrature", self.io.mesh.ufl_cell(), degree=1, quad_scheme="default") Q_scalar = FiniteElement("Quadrature", self.io.mesh.ufl_cell(), degree=1, quad_scheme="default") # not yet working - we cannot interpolate into Quadrature elements with the current dolfinx version currently! #self.Vd_tensor = FunctionSpace(self.io.mesh, Q_tensor) #self.Vd_vector = FunctionSpace(self.io.mesh, Q_vector) #self.Vd_scalar = FunctionSpace(self.io.mesh, Q_scalar) # Quadrature function spaces (currently not properly functioning for higher-order meshes!!!) self.Vd_tensor = TensorFunctionSpace(self.io.mesh, (dg_type, self.order_disp-1)) self.Vd_vector = VectorFunctionSpace(self.io.mesh, (dg_type, self.order_disp-1)) self.Vd_scalar = FunctionSpace(self.io.mesh, (dg_type, self.order_disp-1)) # functions self.du = TrialFunction(self.V_u) # Incremental displacement self.var_u = TestFunction(self.V_u) # Test function self.dp = TrialFunction(self.V_p) # Incremental pressure self.var_p = TestFunction(self.V_p) # Test function self.u = Function(self.V_u, name="Displacement") self.p = Function(self.V_p, name="Pressure") # values of previous time step self.u_old = Function(self.V_u) self.v_old = Function(self.V_u) self.a_old = Function(self.V_u) self.p_old = Function(self.V_p) # a setpoint displacement for multiscale analysis self.u_set = Function(self.V_u) self.p_set = Function(self.V_p) self.tau_a_set = Function(self.Vd_scalar) # initial (zero) functions for initial stiffness evaluation (e.g. for Rayleigh damping) self.u_ini, self.p_ini, self.theta_ini, self.tau_a_ini = Function(self.V_u), Function(self.V_p), Function(self.Vd_scalar), Function(self.Vd_scalar) self.theta_ini.vector.set(1.0) self.theta_ini.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # growth stretch self.theta = Function(self.Vd_scalar, name="theta") self.theta_old = Function(self.Vd_scalar) self.growth_thres = Function(self.Vd_scalar) # initialize to one (theta = 1 means no growth) self.theta.vector.set(1.0), self.theta_old.vector.set(1.0) self.theta.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD), self.theta_old.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # active stress self.tau_a = Function(self.Vd_scalar, name="tau_a") self.tau_a_old = Function(self.Vd_scalar) self.amp_old, self.amp_old_set = Function(self.Vd_scalar), Function(self.Vd_scalar) self.amp_old.vector.set(1.0), self.amp_old_set.vector.set(1.0) self.amp_old.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD), self.amp_old_set.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # prestressing history defgrad and spring prestress if self.prestress_initial: self.F_hist = Function(self.Vd_tensor, name="Defgrad_hist") self.u_pre = Function(self.V_u) else: self.F_hist = None self.u_pre = None self.internalvars = {"theta" : self.theta, "tau_a" : self.tau_a} self.internalvars_old = {"theta" : self.theta_old, "tau_a" : self.tau_a_old} # reference coordinates self.x_ref = Function(self.V_u) self.x_ref.interpolate(self.x_ref_expr) if self.incompressible_2field: self.ndof = self.u.vector.getSize() + self.p.vector.getSize() else: self.ndof = self.u.vector.getSize() # initialize solid time-integration class self.ti = timeintegration.timeintegration_solid(time_params, fem_params, time_curves, self.t_init, self.comm) # check for materials that need extra treatment (anisotropic, active stress, growth, ...) have_fiber1, have_fiber2 = False, False self.have_active_stress, self.active_stress_trig, self.have_frank_starling, self.have_growth = False, 'ode', False, False self.mat_active_stress, self.mat_growth, self.mat_remodel, self.mat_growth_dir, self.mat_growth_trig, self.mat_growth_thres = [False]*self.num_domains, [False]*self.num_domains, [False]*self.num_domains, [None]*self.num_domains, [None]*self.num_domains, []*self.num_domains self.localsolve, growth_dir = False, None self.actstress = [] for n in range(self.num_domains): if 'holzapfelogden_dev' in self.constitutive_models['MAT'+str(n+1)+''].keys() or 'guccione_dev' in self.constitutive_models['MAT'+str(n+1)+''].keys(): have_fiber1, have_fiber2 = True, True if 'active_fiber' in self.constitutive_models['MAT'+str(n+1)+''].keys(): have_fiber1 = True self.mat_active_stress[n], self.have_active_stress = True, True # if one mat has a prescribed active stress, all have to be! if 'prescribed_curve' in self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']: self.active_stress_trig = 'prescribed' if 'prescribed_multiscale' in self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']: self.active_stress_trig = 'prescribed_multiscale' if self.active_stress_trig == 'ode': act_curve = self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']['activation_curve']) self.actstress.append(activestress_activation(self.constitutive_models['MAT'+str(n+1)+'']['active_fiber'], act_curve)) if self.actstress[-1].frankstarling: self.have_frank_starling = True if self.active_stress_trig == 'prescribed': self.ti.funcs_to_update.append({self.tau_a : self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']['prescribed_curve'])}) if 'active_iso' in self.constitutive_models['MAT'+str(n+1)+''].keys(): self.mat_active_stress[n], self.have_active_stress = True, True # if one mat has a prescribed active stress, all have to be! if 'prescribed_curve' in self.constitutive_models['MAT'+str(n+1)+'']['active_iso']: self.active_stress_trig = 'prescribed' if 'prescribed_multiscale' in self.constitutive_models['MAT'+str(n+1)+'']['active_iso']: self.active_stress_trig = 'prescribed_multiscale' if self.active_stress_trig == 'ode': act_curve = self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_iso']['activation_curve']) self.actstress.append(activestress_activation(self.constitutive_models['MAT'+str(n+1)+'']['active_iso'], act_curve)) if self.active_stress_trig == 'prescribed': self.ti.funcs_to_update.append({self.tau_a : self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_iso']['prescribed_curve'])}) if 'growth' in self.constitutive_models['MAT'+str(n+1)+''].keys(): self.mat_growth[n], self.have_growth = True, True self.mat_growth_dir[n] = self.constitutive_models['MAT'+str(n+1)+'']['growth']['growth_dir'] self.mat_growth_trig[n] = self.constitutive_models['MAT'+str(n+1)+'']['growth']['growth_trig'] # need to have fiber fields for the following growth options if self.mat_growth_dir[n] == 'fiber' or self.mat_growth_trig[n] == 'fibstretch': have_fiber1 = True if self.mat_growth_dir[n] == 'radial': have_fiber1, have_fiber2 = True, True # in this case, we have a theta that is (nonlinearly) dependent on the deformation, theta = theta(C(u)), # therefore we need a local Newton iteration to solve for equilibrium theta (return mapping) prior to entering # the global Newton scheme - so flag localsolve to true if self.mat_growth_trig[n] != 'prescribed' and self.mat_growth_trig[n] != 'prescribed_multiscale': self.localsolve = True self.mat_growth_thres.append(self.constitutive_models['MAT'+str(n+1)+'']['growth']['growth_thres']) else: self.mat_growth_thres.append(as_ufl(0)) # for the case that we have a prescribed growth stretch over time, append curve to functions that need time updates # if one mat has a prescribed growth model, all have to be! if self.mat_growth_trig[n] == 'prescribed': self.ti.funcs_to_update.append({self.theta : self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['growth']['prescribed_curve'])}) if 'remodeling_mat' in self.constitutive_models['MAT'+str(n+1)+'']['growth'].keys(): self.mat_remodel[n] = True else: self.mat_growth_thres.append(as_ufl(0)) # full linearization of our remodeling law can lead to excessive compiler times for ffcx... :-/ # let's try if we might can go without one of the critial terms (derivative of remodeling fraction w.r.t. C) try: self.lin_remod_full = fem_params['lin_remodeling_full'] except: self.lin_remod_full = True # growth threshold (as function, since in multiscale approach, it can vary element-wise) if self.have_growth and self.localsolve: growth_thres_proj = project(self.mat_growth_thres, self.Vd_scalar, self.dx_) self.growth_thres.vector.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) self.growth_thres.interpolate(growth_thres_proj) # read in fiber data if have_fiber1: fibarray = ['fiber'] if have_fiber2: fibarray.append('sheet') # fiber function space - vector defined on quadrature points V_fib = self.Vd_vector self.fib_func = self.io.readin_fibers(fibarray, V_fib, self.dx_) else: self.fib_func = None # for multiscale G&R analysis self.tol_stop_large = 0 # initialize kinematics class self.ki = solid_kinematics_constitutive.kinematics(fib_funcs=self.fib_func, F_hist=self.F_hist) # initialize material/constitutive class self.ma = [] for n in range(self.num_domains): self.ma.append(solid_kinematics_constitutive.constitutive(self.ki, self.constitutive_models['MAT'+str(n+1)+''], self.incompressible_2field, mat_growth=self.mat_growth[n], mat_remodel=self.mat_remodel[n])) # initialize solid variational form class self.vf = solid_variationalform.variationalform(self.var_u, self.du, self.var_p, self.dp, self.io.n0, self.x_ref) # initialize boundary condition class self.bc = boundaryconditions.boundary_cond_solid(bc_dict, self.fem_params, self.io, self.ki, self.vf, self.ti) if self.prestress_initial: # initialize prestressing history deformation gradient Id_proj = project(Identity(len(self.u)), self.Vd_tensor, self.dx_) self.F_hist.interpolate(Id_proj) self.bc_dict = bc_dict # Dirichlet boundary conditions if 'dirichlet' in self.bc_dict.keys(): self.bc.dirichlet_bcs(self.V_u) self.set_variational_forms_and_jacobians()
def generateRHS_gpu(field_array, surf_array, param, kernel, timing, ind0): F = zeros(param.Neq) REAL = param.REAL computeRHS_gpu = kernel.get_function("compute_RHS") computeRHSKt_gpu = kernel.get_function("compute_RHSKt") for j in range(len(field_array)): Nq = len(field_array[j].q) if Nq>0: # First for CHILD surfaces for s in field_array[j].child[:]: # Loop over surfaces # Locate position of surface s in RHS s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[ss].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) Nround = len(surf_array[s].twig)*param.NCRIT GSZ = int(ceil(float(Nround)/param.NCRIT)) # CUDA grid size if surf_array[s].surf_type!='asc_surface': F_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHS_gpu(F_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ,1,1), grid=(GSZ,1)) aux = zeros(Nround) F_gpu.get(aux) else: Fx_gpu = gpuarray.zeros(Nround, dtype=REAL) Fy_gpu = gpuarray.zeros(Nround, dtype=REAL) Fz_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHSKt_gpu(Fx_gpu, Fy_gpu, Fz_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ,1,1), grid=(GSZ,1)) aux_x = zeros(Nround) aux_y = zeros(Nround) aux_z = zeros(Nround) Fx_gpu.get(aux_x) Fy_gpu.get(aux_y) Fz_gpu.get(aux_z) aux = aux_x[surf_array[s].unsort]*surf_array[s].normal[:,0] + \ aux_y[surf_array[s].unsort]*surf_array[s].normal[:,1] + \ aux_z[surf_array[s].unsort]*surf_array[s].normal[:,2] # For CHILD surfaces, q contributes to RHS in # EXTERIOR equation (hence Precond[1,:] and [3,:]) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner # F[s_start:s_start+s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[1,:] # F[s_start+s_size:s_start+2*s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[3,:] # With preconditioner # If surface is dirichlet or neumann it has only one equation, affected by Precond[0,:] # We do this only here (and not in the parent case) because interaction of charges # with dirichlet or neumann surface happens only for the surface as a child surfaces. if surf_array[s].surf_type=='dirichlet_surface' or surf_array[s].surf_type=='neumann_surface': F[s_start:s_start+s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[0,:] elif surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += aux*surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[1,:] F[s_start+s_size:s_start+2*s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[3,:] # Now for PARENT surface if len(field_array[j].parent)>0: s = field_array[j].parent[0] # Locate position of surface s in RHS s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[ss].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) Nround = len(surf_array[s].twig)*param.NCRIT GSZ = int(ceil(float(Nround)/param.NCRIT)) # CUDA grid size if surf_array[s].surf_type!='asc_surface': F_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHS_gpu(F_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ,1,1), grid=(GSZ,1)) aux = zeros(Nround) F_gpu.get(aux) else: Fx_gpu = gpuarray.zeros(Nround, dtype=REAL) Fy_gpu = gpuarray.zeros(Nround, dtype=REAL) Fz_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHSKt_gpu(Fx_gpu, Fy_gpu, Fz_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ,1,1), grid=(GSZ,1)) aux_x = zeros(Nround) aux_y = zeros(Nround) aux_z = zeros(Nround) Fx_gpu.get(aux_x) Fy_gpu.get(aux_y) Fz_gpu.get(aux_z) aux = aux_x[surf_array[s].unsort]*surf_array[s].normal[:,0] + \ aux_y[surf_array[s].unsort]*surf_array[s].normal[:,1] + \ aux_z[surf_array[s].unsort]*surf_array[s].normal[:,2] # For PARENT surface, q contributes to RHS in # INTERIOR equation (hence Precond[0,:] and [2,:]) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner if surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += aux*surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[0,:] F[s_start+s_size:s_start+2*s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[2,:] # Dirichlet/Neumann contribution to RHS for j in range(len(field_array)): dirichlet = [] neumann = [] LorY = field_array[j].LorY # Find Dirichlet and Neumann surfaces in region # Dirichlet/Neumann surfaces can only be child of region, # no point on looking at parent surface for s in field_array[j].child: if surf_array[s].surf_type=='dirichlet_surface': dirichlet.append(s) elif surf_array[s].surf_type=='neumann_surface': neumann.append(s) if len(neumann)>0 or len(dirichlet)>0: # First look at influence on SIBLING surfaces for s in field_array[j].child: param.kappa = field_array[j].kappa # Effect of dirichlet surfaces for sd in dirichlet: K_diag = -2*pi*(sd==s) V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf_array[sd].phi0, zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charged surface, the surface has only one equation, # else, s has 2 equations and K_lyr affects the external # equation, which is placed after the internal one, hence # Precond[1,:] and Precond[3,:]. if surf_array[s].surf_type=='dirichlet_surface' or surf_array[s].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += K_lyr * surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += K_lyr * surf_array[s].Precond[1,:] F[s_start+s_size:s_start+2*s_size] += K_lyr * surf_array[s].Precond[3,:] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project(zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charged surface, the surface has only one equation, # else, s has 2 equations and V_lyr affects the external # equation, which is placed after the internal one, hence # Precond[1,:] and Precond[3,:]. if surf_array[s].surf_type=='dirichlet_surface' or surf_array[s].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += -V_lyr * surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += -V_lyr * surf_array[s].Precond[1,:] F[s_start+s_size:s_start+2*s_size] += -V_lyr * surf_array[s].Precond[3,:] # Now look at influence on PARENT surface # The dirichlet/neumann surface will never be the parent, # since we are not solving for anything inside them. # Then, in this case we will not look at self interaction. if len(field_array[j].parent)==1: s = field_array[j].parent[0] # Effect of dirichlet surfaces for sd in dirichlet: K_diag = 0 V_diag = 0 IorE = 1 K_lyr, V_lyr = project(surf_array[sd].phi0, zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start+s_size] += K_lyr * surf_array[s].Precond[0,:] F[s_start+s_size:s_start+2*s_size] += K_lyr * surf_array[s].Precond[2,:] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 1 K_lyr, V_lyr = project(zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start+s_size] += -V_lyr * surf_array[s].Precond[0,:] F[s_start+s_size:s_start+2*s_size] += -V_lyr * surf_array[s].Precond[2,:] return F
def write_output(self, pb, writemesh=False, N=1, t=0): if writemesh: if self.write_results_every > 0: self.resultsfiles = {} for res in self.results_to_write: outfile = XDMFFile(self.comm, self.output_path+'/results_'+pb.simname+'_'+res+'.xdmf', 'w') outfile.write_mesh(self.mesh) self.resultsfiles[res] = outfile return else: # write results every write_results_every steps if self.write_results_every > 0 and N % self.write_results_every == 0: # save solution to XDMF format for res in self.results_to_write: if res=='displacement': self.resultsfiles[res].write_function(pb.u, t) elif res=='velocity': # passed in v is not a function but form, so we have to project v_proj = project(pb.vel, pb.V_u, pb.dx_, nm="Velocity") self.resultsfiles[res].write_function(v_proj, t) elif res=='acceleration': # passed in a is not a function but form, so we have to project a_proj = project(pb.acc, pb.V_u, pb.dx_, nm="Acceleration") self.resultsfiles[res].write_function(a_proj, t) elif res=='pressure': self.resultsfiles[res].write_function(pb.p, t) elif res=='cauchystress': stressfuncs=[] for n in range(pb.num_domains): stressfuncs.append(pb.ma[n].sigma(pb.u,pb.p,ivar=pb.internalvars)) cauchystress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="CauchyStress") self.resultsfiles[res].write_function(cauchystress, t) elif res=='trmandelstress': stressfuncs=[] for n in range(pb.num_domains): stressfuncs.append(tr(pb.ma[n].M(pb.u,pb.p,ivar=pb.internalvars))) trmandelstress = project(stressfuncs, pb.Vd_scalar, pb.dx_, nm="trMandelStress") self.resultsfiles[res].write_function(trmandelstress, t) elif res=='trmandelstress_e': stressfuncs=[] for n in range(pb.num_domains): if pb.mat_growth[n]: stressfuncs.append(tr(pb.ma[n].M_e(pb.u,pb.p,pb.ki.C(pb.u),ivar=pb.internalvars))) else: stressfuncs.append(as_ufl(0)) trmandelstress_e = project(stressfuncs, pb.Vd_scalar, pb.dx_, nm="trMandelStress_e") self.resultsfiles[res].write_function(trmandelstress_e, t) elif res=='vonmises_cauchystress': stressfuncs=[] for n in range(pb.num_domains): stressfuncs.append(pb.ma[n].sigma_vonmises(pb.u,pb.p,ivar=pb.internalvars)) vonmises_cauchystress = project(stressfuncs, pb.Vd_scalar, pb.dx_, nm="vonMises_CauchyStress") self.resultsfiles[res].write_function(vonmises_cauchystress, t) elif res=='pk1stress': stressfuncs=[] for n in range(pb.num_domains): stressfuncs.append(pb.ma[n].P(pb.u,pb.p,ivar=pb.internalvars)) pk1stress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="PK1Stress") self.resultsfiles[res].write_function(pk1stress, t) elif res=='pk2stress': stressfuncs=[] for n in range(pb.num_domains): stressfuncs.append(pb.ma[n].S(pb.u,pb.p,ivar=pb.internalvars)) pk2stress = project(stressfuncs, pb.Vd_tensor, pb.dx_, nm="PK2Stress") self.resultsfiles[res].write_function(pk2stress, t) elif res=='jacobian': jacobian = project(pb.ki.J(pb.u), pb.Vd_scalar, pb.dx_, nm="Jacobian") self.resultsfiles[res].write_function(jacobian, t) elif res=='glstrain': glstrain = project(pb.ki.E(pb.u), pb.Vd_tensor, pb.dx_, nm="GreenLagrangeStrain") self.resultsfiles[res].write_function(glstrain, t) elif res=='eastrain': eastrain = project(pb.ki.e(pb.u), pb.Vd_tensor, pb.dx_, nm="EulerAlmansiStrain") self.resultsfiles[res].write_function(eastrain, t) elif res=='fiberstretch': fiberstretch = project(pb.ki.fibstretch(pb.u,pb.fib_func[0]), pb.Vd_scalar, pb.dx_, nm="FiberStretch") self.resultsfiles[res].write_function(fiberstretch, t) elif res=='fiberstretch_e': stretchfuncs=[] for n in range(pb.num_domains): if pb.mat_growth[n]: stretchfuncs.append(pb.ma[n].fibstretch_e(pb.ki.C(pb.u),pb.theta,pb.fib_func[0])) else: stretchfuncs.append(as_ufl(0)) fiberstretch_e = project(stretchfuncs, pb.Vd_scalar, pb.dx_, nm="FiberStretch_e") self.resultsfiles[res].write_function(fiberstretch_e, t) elif res=='theta': self.resultsfiles[res].write_function(pb.theta, t) elif res=='phi_remod': phifuncs=[] for n in range(pb.num_domains): if pb.mat_remodel[n]: phifuncs.append(pb.ma[n].phi_remod(pb.theta)) else: phifuncs.append(as_ufl(0)) phiremod = project(phifuncs, pb.Vd_scalar, pb.dx_, nm="phiRemodel") self.resultsfiles[res].write_function(phiremod, t) elif res=='tau_a': self.resultsfiles[res].write_function(pb.tau_a, t) elif res=='fiber1': fiber1 = project(pb.fib_func[0], pb.Vd_vector, pb.dx_, nm="Fiber1") self.resultsfiles[res].write_function(fiber1, t) elif res=='fiber2': fiber2 = project(pb.fib_func[1], pb.Vd_vector, pb.dx_, nm="Fiber2") self.resultsfiles[res].write_function(fiber2, t) else: raise NameError("Unknown output to write for solid mechanics!") if self.write_restart_every > 0 and N % self.write_restart_every == 0: self.writecheckpoint(pb, N)
name, sequence = line.split() seqs[name] = sequence f.close() fname = "result_" + str(randint(1, 10000000)) print "Storing results in ", fname with open(fname, 'w') as f: for one_item in seqs.items(): seq_name= one_item[0] print "Running experiment on ", seq_name gapped_sequence = one_item[1] ungapped_sequnce = gapped_sequence.replace("-", "") projected_real_structure = project(gapped_sequence, true_5s) ungapped_real_structure = projected_real_structure.replace("-", "") assert len(ungapped_sequnce) == len(ungapped_real_structure) mfe_prediction = get_mfe(cleaned(gapped_sequence)) assert len(mfe_prediction) == len(ungapped_real_structure) mfe_score = bp_distance(mfe_prediction, ungapped_real_structure) print "MFE distance: ", mfe_score classical_prediction = most_probable_from_real(cleaned(gapped_sequence)).most_common()[0][0] assert len(classical_prediction) == len(ungapped_real_structure) classical_score = bp_distance(classical_prediction, ungapped_real_structure) print "Classical BP distance: ", classical_score mutant_prediction = most_probable_from_mutants(cleaned(gapped_sequence)).most_common()[0][0] assert len(mutant_prediction) == len(ungapped_real_structure)
name, sequence = line.split() seqs[name] = sequence f.close() fname = "result_" + str(randint(1, 10000000)) print "Storing results in ", fname with open(fname, 'w') as f: for one_item in seqs.items(): seq_name = one_item[0] print "Running experiment on ", seq_name gapped_sequence = one_item[1] ungapped_sequnce = gapped_sequence.replace("-", "") projected_real_structure = project(gapped_sequence, true_5s) ungapped_real_structure = projected_real_structure.replace("-", "") assert len(ungapped_sequnce) == len(ungapped_real_structure) mfe_prediction = get_mfe(cleaned(gapped_sequence)) assert len(mfe_prediction) == len(ungapped_real_structure) mfe_score = bp_distance(mfe_prediction, ungapped_real_structure) print "MFE distance: ", mfe_score classical_prediction = most_probable_from_real( cleaned(gapped_sequence)).most_common()[0][0] assert len(classical_prediction) == len(ungapped_real_structure) classical_score = bp_distance(classical_prediction, ungapped_real_structure) print "Classical BP distance: ", classical_score
def generateRHS(field_array, surf_array, param, kernel, timing, ind0): F = numpy.zeros(param.Neq) # Point charge contribution to RHS for j in range(len(field_array)): Nq = len(field_array[j].q) if Nq > 0: # First look at CHILD surfaces for s in field_array[j].child: # Loop over surfaces # Locate position of surface s in RHS s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ ss].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) aux = numpy.zeros(len(surf_array[s].xi)) for i in range(Nq): dx_pq = surf_array[s].xi - field_array[j].xq[i, 0] dy_pq = surf_array[s].yi - field_array[j].xq[i, 1] dz_pq = surf_array[s].zi - field_array[j].xq[i, 2] R_pq = numpy.sqrt(dx_pq * dx_pq + dy_pq * dy_pq + dz_pq * dz_pq) if surf_array[s].surf_type == 'asc_surface': aux -= field_array[j].q[i]/(R_pq*R_pq*R_pq) * (dx_pq*surf_array[s].normal[:,0] \ + dy_pq*surf_array[s].normal[:,1] \ + dz_pq*surf_array[s].normal[:,2]) else: aux += field_array[j].q[i] / (field_array[j].E * R_pq) # For CHILD surfaces, q contributes to RHS in # EXTERIOR equation (hence Precond[1,:] and [3,:]) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner # If surface is dirichlet or neumann it has only one equation, affected by Precond[0,:] # We do this only here (and not in the parent case) because interaction of charges # with dirichlet or neumann surface happens only for the surface as a child surfaces. if surf_array[s].surf_type == 'dirichlet_surface' or surf_array[ s].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += aux * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += aux * surf_array[s].Precond[1, :] F[s_start + s_size:s_start + 2 * s_size] += aux * surf_array[s].Precond[3, :] # Now look at PARENT surface if len(field_array[j].parent) > 0: # Locate position of surface s in RHS s = field_array[j].parent[0] s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ ss].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) aux = numpy.zeros(len(surf_array[s].xi)) for i in range(Nq): dx_pq = surf_array[s].xi - field_array[j].xq[i, 0] dy_pq = surf_array[s].yi - field_array[j].xq[i, 1] dz_pq = surf_array[s].zi - field_array[j].xq[i, 2] R_pq = numpy.sqrt(dx_pq * dx_pq + dy_pq * dy_pq + dz_pq * dz_pq) if surf_array[s].surf_type == 'asc_surface': aux -= field_array[j].q[i]/(R_pq*R_pq*R_pq) * (dx_pq*surf_array[s].normal[:,0] \ + dy_pq*surf_array[s].normal[:,1] \ + dz_pq*surf_array[s].normal[:,2]) else: aux += field_array[j].q[i] / (field_array[j].E * R_pq) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner if surf_array[s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += aux * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += aux * surf_array[s].Precond[0, :] F[s_start + s_size:s_start + 2 * s_size] += aux * surf_array[s].Precond[2, :] # Dirichlet/Neumann contribution to RHS for j in range(len(field_array)): dirichlet = [] neumann = [] LorY = field_array[j].LorY # Find Dirichlet and Neumann surfaces in region # Dirichlet/Neumann surfaces can only be child of region, # no point on looking at parent surface for s in field_array[j].child: if surf_array[s].surf_type == 'dirichlet_surface': dirichlet.append(s) elif surf_array[s].surf_type == 'neumann_surface': neumann.append(s) if len(neumann) > 0 or len(dirichlet) > 0: # First look at influence on SIBLING surfaces for s in field_array[j].child: param.kappa = field_array[j].kappa # Effect of dirichlet surfaces for sd in dirichlet: K_diag = -2 * pi * (sd == s) V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf_array[sd].phi0, numpy.zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charged surface, the surface has only one equation, # else, s has 2 equations and K_lyr affects the external # equation (SIBLING surfaces), which is placed after the internal # one, hence Precond[1,:] and Precond[3,:]. if surf_array[ s].surf_type == 'dirichlet_surface' or surf_array[ s].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += K_lyr * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += K_lyr * surf_array[s].Precond[1, :] F[s_start + s_size:s_start + 2 * s_size] += K_lyr * surf_array[s].Precond[3, :] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project( numpy.zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charge surface, the surface has only one equation, # else, s has 2 equations and V_lyr affects the external # equation, which is placed after the internal one, hence # Precond[1,:] and Precond[3,:]. if surf_array[ s].surf_type == 'dirichlet_surface' or surf_array[ s].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += -V_lyr * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += -V_lyr * surf_array[s].Precond[1, :] F[s_start + s_size:s_start + 2 * s_size] += -V_lyr * surf_array[s].Precond[3, :] # Now look at influence on PARENT surface # The dirichlet/neumann surface will never be the parent, # since we are not solving for anything inside them. # Then, in this case we will not look at self interaction, # which is dealt with by the sibling surface section if len(field_array[j].parent) == 1: s = field_array[j].parent[0] # Effect of dirichlet surfaces for sd in dirichlet: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf_array[sd].phi0, numpy.zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start + s_size] += K_lyr * surf_array[s].Precond[0, :] F[s_start + s_size:s_start + 2 * s_size] += K_lyr * surf_array[s].Precond[2, :] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project( numpy.zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start + s_size] += -V_lyr * surf_array[s].Precond[0, :] F[s_start + s_size:s_start + 2 * s_size] += -V_lyr * surf_array[s].Precond[2, :] return F
def generateRHS(field_array, surf_array, param, kernel, timing, ind0): F = zeros(param.Neq) # Point charge contribution to RHS for j in range(len(field_array)): Nq = len(field_array[j].q) if Nq>0: # First look at CHILD surfaces for s in field_array[j].child: # Loop over surfaces # Locate position of surface s in RHS s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[ss].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) aux = zeros(len(surf_array[s].xi)) for i in range(Nq): dx_pq = surf_array[s].xi - field_array[j].xq[i,0] dy_pq = surf_array[s].yi - field_array[j].xq[i,1] dz_pq = surf_array[s].zi - field_array[j].xq[i,2] R_pq = sqrt(dx_pq*dx_pq + dy_pq*dy_pq + dz_pq*dz_pq) if surf_array[s].surf_type=='asc_surface': aux -= field_array[j].q[i]/(R_pq*R_pq*R_pq) * (dx_pq*surf_array[s].normal[:,0] \ + dy_pq*surf_array[s].normal[:,1] \ + dz_pq*surf_array[s].normal[:,2]) else: aux += field_array[j].q[i]/(field_array[j].E*R_pq) # For CHILD surfaces, q contributes to RHS in # EXTERIOR equation (hence Precond[1,:] and [3,:]) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner # If surface is dirichlet or neumann it has only one equation, affected by Precond[0,:] # We do this only here (and not in the parent case) because interaction of charges # with dirichlet or neumann surface happens only for the surface as a child surfaces. if surf_array[s].surf_type=='dirichlet_surface' or surf_array[s].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += aux*surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += aux*surf_array[s].Precond[1,:] F[s_start+s_size:s_start+2*s_size] += aux*surf_array[s].Precond[3,:] # Now look at PARENT surface if len(field_array[j].parent)>0: # Locate position of surface s in RHS s = field_array[j].parent[0] s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[ss].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) aux = zeros(len(surf_array[s].xi)) for i in range(Nq): dx_pq = surf_array[s].xi - field_array[j].xq[i,0] dy_pq = surf_array[s].yi - field_array[j].xq[i,1] dz_pq = surf_array[s].zi - field_array[j].xq[i,2] R_pq = sqrt(dx_pq*dx_pq + dy_pq*dy_pq + dz_pq*dz_pq) if surf_array[s].surf_type=='asc_surface': aux -= field_array[j].q[i]/(R_pq*R_pq*R_pq) * (dx_pq*surf_array[s].normal[:,0] \ + dy_pq*surf_array[s].normal[:,1] \ + dz_pq*surf_array[s].normal[:,2]) else: aux += field_array[j].q[i]/(field_array[j].E*R_pq) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner if surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += aux*surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += aux*surf_array[s].Precond[0,:] F[s_start+s_size:s_start+2*s_size] += aux*surf_array[s].Precond[2,:] # Dirichlet/Neumann contribution to RHS for j in range(len(field_array)): dirichlet = [] neumann = [] LorY = field_array[j].LorY # Find Dirichlet and Neumann surfaces in region # Dirichlet/Neumann surfaces can only be child of region, # no point on looking at parent surface for s in field_array[j].child: if surf_array[s].surf_type=='dirichlet_surface': dirichlet.append(s) elif surf_array[s].surf_type=='neumann_surface': neumann.append(s) if len(neumann)>0 or len(dirichlet)>0: # First look at influence on SIBLING surfaces for s in field_array[j].child: param.kappa = field_array[j].kappa # Effect of dirichlet surfaces for sd in dirichlet: K_diag = -2*pi*(sd==s) V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf_array[sd].phi0, zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charged surface, the surface has only one equation, # else, s has 2 equations and K_lyr affects the external # equation (SIBLING surfaces), which is placed after the internal # one, hence Precond[1,:] and Precond[3,:]. if surf_array[s].surf_type=='dirichlet_surface' or surf_array[s].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += K_lyr * surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += K_lyr * surf_array[s].Precond[1,:] F[s_start+s_size:s_start+2*s_size] += K_lyr * surf_array[s].Precond[3,:] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project(zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charge surface, the surface has only one equation, # else, s has 2 equations and V_lyr affects the external # equation, which is placed after the internal one, hence # Precond[1,:] and Precond[3,:]. if surf_array[s].surf_type=='dirichlet_surface' or surf_array[s].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': F[s_start:s_start+s_size] += -V_lyr * surf_array[s].Precond[0,:] else: F[s_start:s_start+s_size] += -V_lyr * surf_array[s].Precond[1,:] F[s_start+s_size:s_start+2*s_size] += -V_lyr * surf_array[s].Precond[3,:] # Now look at influence on PARENT surface # The dirichlet/neumann surface will never be the parent, # since we are not solving for anything inside them. # Then, in this case we will not look at self interaction, # which is dealt with by the sibling surface section if len(field_array[j].parent)==1: s = field_array[j].parent[0] # Effect of dirichlet surfaces for sd in dirichlet: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf_array[sd].phi0, zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start+s_size] += K_lyr * surf_array[s].Precond[0,:] F[s_start+s_size:s_start+2*s_size] += K_lyr * surf_array[s].Precond[2,:] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project(zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ss].surf_type=='dirichlet_surface' or surf_array[ss].surf_type=='neumann_surface' or surf_array[s].surf_type=='asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2*len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start+s_size] += -V_lyr * surf_array[s].Precond[0,:] F[s_start+s_size:s_start+2*s_size] += -V_lyr * surf_array[s].Precond[2,:] return F
def __lshift__(self, data): """It allows file << function syntax for writing data out to disk. In the case of parallel, it would also accept (function, timestep) tuple as an argument. If only function is given, then the timestep will be automatically generated.""" # If parallel, it needs to keep track of its timestep. if MPI.parallel: # if statements to keep the consistency of how to update the # timestep. if isinstance(data, tuple): if self._time_step == -1 or not self._generate_time: function = data[0] self._time_step = data[1] else: raise TypeError("Expected function, got tuple.") else: if self._time_step != -1 and not self._generate_time: raise TypeError("Expected tuple, got function.") function = data self._time_step += 1 self._generate_time = True else: function = data def is_family1(e, family): import ufl.finiteelement.hdivcurl as hc if isinstance(e, (hc.HDiv, hc.HCurl)): return False if e.family() == 'OuterProductElement': if e.degree() == (1, 1): if e._A.family() == family \ and e._B.family() == family: return True elif e.family() == family and e.degree() == 1: return True return False def is_cgN(e): import ufl.finiteelement.hdivcurl as hc if isinstance(e, (hc.HDiv, hc.HCurl)): return False if e.family() == 'OuterProductElement': if e._A.family() == 'Lagrange' \ and e._B.family() == 'Lagrange': return True elif e.family() == 'Lagrange': return True return False mesh = function.function_space().mesh() e = function.function_space().ufl_element() if len(e.value_shape()) > 1: raise RuntimeError("Can't output tensor valued functions") ce = mesh.coordinates.function_space().ufl_element() coords_p1 = is_family1(ce, 'Lagrange') coords_p1dg = is_family1(ce, 'Discontinuous Lagrange') coords_cgN = is_cgN(ce) function_p1 = is_family1(e, 'Lagrange') function_p1dg = is_family1(e, 'Discontinuous Lagrange') function_cgN = is_cgN(e) project_coords = False project_function = False discontinuous = False # We either output in P1 or P1dg. if coords_cgN and function_cgN: family = 'CG' project_coords = not coords_p1 project_function = not function_p1 else: family = 'DG' project_coords = not coords_p1dg project_function = not function_p1dg discontinuous = True if project_function: if len(e.value_shape()) == 0: Vo = fs.FunctionSpace(mesh, family, 1) elif len(e.value_shape()) == 1: Vo = fs.VectorFunctionSpace(mesh, family, 1, dim=e.value_shape()[0]) else: # Never reached Vo = None if not self._warnings[0]: warning(RED % "*** Projecting output function to %s1", family) self._warnings[0] = True output = projection.project(function, Vo, name=function.name()) else: output = function Vo = output.function_space() if project_coords: Vc = fs.VectorFunctionSpace(mesh, family, 1, dim=mesh._coordinate_fs.dim) if not self._warnings[1]: warning(RED % "*** Projecting coordinates to %s1", family) self._warnings[1] = True coordinates = projection.project(mesh.coordinates, Vc, name=mesh.coordinates.name()) else: coordinates = mesh.coordinates Vc = coordinates.function_space() num_points = Vo.node_count if not (e.family() == "OuterProductElement"): num_cells = mesh.num_cells() else: num_cells = mesh.num_cells() * (mesh.layers - 1) if not (e.family() == "OuterProductElement"): connectivity = Vc.cell_node_map().values_with_halo.flatten() else: # Connectivity of bottom cell in extruded mesh base = Vc.cell_node_map().values_with_halo if _cells[mesh._ufl_cell] == hl.VtkQuad: # Quad is # # 1--3 # | | # 0--2 # # needs to be # # 3--2 # | | # 0--1 base = base[:, [0, 2, 3, 1]] points_per_cell = 4 elif _cells[mesh._ufl_cell] == hl.VtkWedge: # Wedge is # # 5 # /|\ # / | \ # 1----3 # | 4 | # | /\ | # |/ \| # 0----2 # # needs to be # # 5 # /|\ # / | \ # 3----4 # | 2 | # | /\ | # |/ \| # 0----1 # base = base[:, [0, 2, 4, 1, 3, 5]] points_per_cell = 6 # Repeat up the column connectivity_temp = np.repeat(base, mesh.layers - 1, axis=0) if discontinuous: scale = points_per_cell else: scale = 1 offsets = np.arange(mesh.layers - 1) * scale # Add offsets going up the column connectivity_temp += np.tile(offsets.reshape(-1, 1), (mesh.num_cells(), 1)) connectivity = connectivity_temp.flatten() if isinstance(output.function_space(), fs.VectorFunctionSpace): tmp = output.dat.data_ro_with_halos vdata = [None]*3 if output.dat.dim[0] == 1: vdata[0] = tmp.flatten() else: for i in range(output.dat.dim[0]): vdata[i] = tmp[:, i].flatten() for i in range(output.dat.dim[0], 3): vdata[i] = np.zeros_like(vdata[0]) data = tuple(vdata) # only for checking large file size flat_data = {function.name(): tmp.flatten()} else: data = output.dat.data_ro_with_halos.flatten() flat_data = {function.name(): data} coordinates = self._fd_to_evtk_coord(coordinates.dat.data_ro_with_halos) cell_types = np.empty(num_cells, dtype="uint8") # Assume that all cells are of same shape. cell_types[:] = _cells[mesh._ufl_cell].tid p_c = _points_per_cell[mesh._ufl_cell] # This tells which are the last nodes of each cell. offsets = np.arange(start=p_c, stop=p_c * (num_cells + 1), step=p_c, dtype='int32') large_file_flag = _requiresLargeVTKFileSize("VtkUnstructuredGrid", numPoints=num_points, numCells=num_cells, pointData=flat_data, cellData=None) new_name = self._filename # When vtu file makes part of a parallel process, aggregated by a # pvtu file, the output is : filename_timestep_rank.vtu if MPI.parallel: new_name += "_" + str(self._time_step) + "_" + str(MPI.comm.rank) self._writer = hl.VtkFile( new_name, hl.VtkUnstructuredGrid, large_file_flag) self._writer.openGrid() self._writer.openPiece(ncells=num_cells, npoints=num_points) # openElement allows the stuff in side of the tag <arg></arg> # to be editted. self._writer.openElement("Points") # addData adds the DataArray in the tag <arg1> self._writer.addData("Points", coordinates) self._writer.closeElement("Points") self._writer.openElement("Cells") self._writer.addData("connectivity", connectivity) self._writer.addData("offsets", offsets) self._writer.addData("types", cell_types) self._writer.closeElement("Cells") self._writer.openData("Point", scalars=function.name()) self._writer.addData(function.name(), data) self._writer.closeData("Point") self._writer.closePiece() self._writer.closeGrid() # Create the AppendedData self._writer.appendData(coordinates) self._writer.appendData(connectivity) self._writer.appendData(offsets) self._writer.appendData(cell_types) self._writer.appendData(data) self._writer.save()
def generateRHS_gpu(field_array, surf_array, param, kernel, timing, ind0): F = numpy.zeros(param.Neq) REAL = param.REAL computeRHS_gpu = kernel.get_function("compute_RHS") computeRHSKt_gpu = kernel.get_function("compute_RHSKt") for j in range(len(field_array)): Nq = len(field_array[j].q) if Nq > 0: # First for CHILD surfaces for s in field_array[j].child[:]: # Loop over surfaces # Locate position of surface s in RHS s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ ss].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) Nround = len(surf_array[s].twig) * param.NCRIT GSZ = int(numpy.ceil(float(Nround) / param.NCRIT)) # CUDA grid size if surf_array[s].surf_type != 'asc_surface': F_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHS_gpu(F_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ, 1, 1), grid=(GSZ, 1)) aux = numpy.zeros(Nround) F_gpu.get(aux) else: Fx_gpu = gpuarray.zeros(Nround, dtype=REAL) Fy_gpu = gpuarray.zeros(Nround, dtype=REAL) Fz_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHSKt_gpu(Fx_gpu, Fy_gpu, Fz_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ, 1, 1), grid=(GSZ, 1)) aux_x = numpy.zeros(Nround) aux_y = numpy.zeros(Nround) aux_z = numpy.zeros(Nround) Fx_gpu.get(aux_x) Fy_gpu.get(aux_y) Fz_gpu.get(aux_z) aux = aux_x[surf_array[s].unsort]*surf_array[s].normal[:,0] + \ aux_y[surf_array[s].unsort]*surf_array[s].normal[:,1] + \ aux_z[surf_array[s].unsort]*surf_array[s].normal[:,2] # For CHILD surfaces, q contributes to RHS in # EXTERIOR equation (hence Precond[1,:] and [3,:]) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner # F[s_start:s_start+s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[1,:] # F[s_start+s_size:s_start+2*s_size] += aux[surf_array[s].unsort]*surf_array[s].Precond[3,:] # With preconditioner # If surface is dirichlet or neumann it has only one equation, affected by Precond[0,:] # We do this only here (and not in the parent case) because interaction of charges # with dirichlet or neumann surface happens only for the surface as a child surfaces. if surf_array[s].surf_type == 'dirichlet_surface' or surf_array[ s].surf_type == 'neumann_surface': F[s_start:s_start + s_size] += aux[ surf_array[s].unsort] * surf_array[s].Precond[0, :] elif surf_array[s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += aux * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += aux[ surf_array[s].unsort] * surf_array[s].Precond[1, :] F[s_start + s_size:s_start + 2 * s_size] += aux[ surf_array[s].unsort] * surf_array[s].Precond[3, :] # Now for PARENT surface if len(field_array[j].parent) > 0: s = field_array[j].parent[0] # Locate position of surface s in RHS s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ ss].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) Nround = len(surf_array[s].twig) * param.NCRIT GSZ = int(numpy.ceil(float(Nround) / param.NCRIT)) # CUDA grid size if surf_array[s].surf_type != 'asc_surface': F_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHS_gpu(F_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ, 1, 1), grid=(GSZ, 1)) aux = numpy.zeros(Nround) F_gpu.get(aux) else: Fx_gpu = gpuarray.zeros(Nround, dtype=REAL) Fy_gpu = gpuarray.zeros(Nround, dtype=REAL) Fz_gpu = gpuarray.zeros(Nround, dtype=REAL) computeRHSKt_gpu(Fx_gpu, Fy_gpu, Fz_gpu, field_array[j].xq_gpu, field_array[j].yq_gpu, field_array[j].zq_gpu, field_array[j].q_gpu, surf_array[s].xiDev, surf_array[s].yiDev, surf_array[s].ziDev, surf_array[s].sizeTarDev, int32(Nq), REAL(field_array[j].E), int32(param.NCRIT), int32(param.BlocksPerTwig), block=(param.BSZ, 1, 1), grid=(GSZ, 1)) aux_x = numpy.zeros(Nround) aux_y = numpy.zeros(Nround) aux_z = numpy.zeros(Nround) Fx_gpu.get(aux_x) Fy_gpu.get(aux_y) Fz_gpu.get(aux_z) aux = aux_x[surf_array[s].unsort]*surf_array[s].normal[:,0] + \ aux_y[surf_array[s].unsort]*surf_array[s].normal[:,1] + \ aux_z[surf_array[s].unsort]*surf_array[s].normal[:,2] # For PARENT surface, q contributes to RHS in # INTERIOR equation (hence Precond[0,:] and [2,:]) # No preconditioner # F[s_start:s_start+s_size] += aux # With preconditioner if surf_array[s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += aux * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += aux[ surf_array[s].unsort] * surf_array[s].Precond[0, :] F[s_start + s_size:s_start + 2 * s_size] += aux[ surf_array[s].unsort] * surf_array[s].Precond[2, :] # Dirichlet/Neumann contribution to RHS for j in range(len(field_array)): dirichlet = [] neumann = [] LorY = field_array[j].LorY # Find Dirichlet and Neumann surfaces in region # Dirichlet/Neumann surfaces can only be child of region, # no point on looking at parent surface for s in field_array[j].child: if surf_array[s].surf_type == 'dirichlet_surface': dirichlet.append(s) elif surf_array[s].surf_type == 'neumann_surface': neumann.append(s) if len(neumann) > 0 or len(dirichlet) > 0: # First look at influence on SIBLING surfaces for s in field_array[j].child: param.kappa = field_array[j].kappa # Effect of dirichlet surfaces for sd in dirichlet: K_diag = -2 * pi * (sd == s) V_diag = 0 IorE = 2 K_lyr, V_lyr = project(surf_array[sd].phi0, numpy.zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charged surface, the surface has only one equation, # else, s has 2 equations and K_lyr affects the external # equation, which is placed after the internal one, hence # Precond[1,:] and Precond[3,:]. if surf_array[ s].surf_type == 'dirichlet_surface' or surf_array[ s].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += K_lyr * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += K_lyr * surf_array[s].Precond[1, :] F[s_start + s_size:s_start + 2 * s_size] += K_lyr * surf_array[s].Precond[3, :] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 2 K_lyr, V_lyr = project( numpy.zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # if s is a charged surface, the surface has only one equation, # else, s has 2 equations and V_lyr affects the external # equation, which is placed after the internal one, hence # Precond[1,:] and Precond[3,:]. if surf_array[ s].surf_type == 'dirichlet_surface' or surf_array[ s].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': F[s_start:s_start + s_size] += -V_lyr * surf_array[s].Precond[0, :] else: F[s_start:s_start + s_size] += -V_lyr * surf_array[s].Precond[1, :] F[s_start + s_size:s_start + 2 * s_size] += -V_lyr * surf_array[s].Precond[3, :] # Now look at influence on PARENT surface # The dirichlet/neumann surface will never be the parent, # since we are not solving for anything inside them. # Then, in this case we will not look at self interaction. if len(field_array[j].parent) == 1: s = field_array[j].parent[0] # Effect of dirichlet surfaces for sd in dirichlet: K_diag = 0 V_diag = 0 IorE = 1 K_lyr, V_lyr = project(surf_array[sd].phi0, numpy.zeros(len(surf_array[sd].xi)), LorY, surf_array[sd], surf_array[s], K_diag, V_diag, IorE, sd, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start + s_size] += K_lyr * surf_array[s].Precond[0, :] F[s_start + s_size:s_start + 2 * s_size] += K_lyr * surf_array[s].Precond[2, :] # Effect of neumann surfaces for sn in neumann: K_diag = 0 V_diag = 0 IorE = 1 K_lyr, V_lyr = project( numpy.zeros(len(surf_array[sn].phi0)), surf_array[sn].phi0, LorY, surf_array[sn], surf_array[s], K_diag, V_diag, IorE, sn, param, ind0, timing, kernel) # Find location of surface s in RHS array s_start = 0 for ss in range(s): if surf_array[ ss].surf_type == 'dirichlet_surface' or surf_array[ ss].surf_type == 'neumann_surface' or surf_array[ s].surf_type == 'asc_surface': s_start += len(surf_array[ss].xi) else: s_start += 2 * len(surf_array[ss].xi) s_size = len(surf_array[s].xi) # Surface s has 2 equations and K_lyr affects the internal # equation, hence Precond[0,:] and Precond[2,:]. F[s_start:s_start + s_size] += -V_lyr * surf_array[s].Precond[0, :] F[s_start + s_size:s_start + 2 * s_size] += -V_lyr * surf_array[s].Precond[2, :] return F