Exemple #1
0
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
Exemple #2
0
    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!")
Exemple #3
0
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)
Exemple #4
0
    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)
Exemple #5
0
    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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
    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)
Exemple #9
0
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
Exemple #10
0
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
Exemple #11
0
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
Exemple #12
0
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
Exemple #13
0
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
Exemple #14
0
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
Exemple #15
0
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()
Exemple #16
0
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
Exemple #17
0
 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)
Exemple #19
0
        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
Exemple #20
0
    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)
Exemple #21
0
 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
Exemple #22
0
# 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)
Exemple #23
0
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
Exemple #24
0
    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()
Exemple #25
0
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
Exemple #26
0
    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
Exemple #29
0
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
Exemple #30
0
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
Exemple #31
0
    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()
Exemple #32
0
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