示例#1
0
    def pv(self):
        if self.__pv is None and self.__upv is not None:
            self.__pv = fe.Function(V_pv)

        fe.assign(self.__pv.sub(0), self.upv.sub(1))
        fe.assign(self.__pv.sub(1), self.upv.sub(2))
        return self.__pv
示例#2
0
 def restart(self):
     logPERIODIC('restart')
     self.t = self.t0
     U0comps = evenodd_functions(
         omesh=self.omesh,
         degree=self.degree,
         func=self.U0,
         evenodd=self.symmetries,
         width=self.xmax
     )
     rho0comps = evenodd_functions(
         omesh=self.omesh,
         degree=self.degree,
         func=self.rho0,
         evenodd=self.symmetries,
         width=self.xmax
     )
     coords = gather_dof_coords(rho0comps[0].function_space())
     for i in range(2**self.dim):
         fe.assign(self.sol.sub(i),
                   function_interpolate(rho0comps[i],
                                        self.SS,
                                        coords=coords))
         fe.assign(self.sol.sub(i + 2**self.dim),
                   function_interpolate(U0comps[i],
                                        self.SS,
                                        coords=coords))
示例#3
0
文件: ksdgvar.py 项目: leonavery/KSDG
 def restart(self):
     logVARIABLE('restart')
     self.set_time(self.t0)
     CE = FiniteElement('CG', cellShapes[self.dim - 1], self.degree)
     CS = FunctionSpace(self.mesh, CE)  # scalar space
     coords = gather_dof_coords(CS)
     fe.assign(self.sol.sub(0),
               function_interpolate(self.rho0, self.SS, coords=coords))
     for i, U0i in enumerate(self.U0s):
         fe.assign(self.sol.sub(i + 1),
                   function_interpolate(U0i, self.SS, coords=coords))
示例#4
0
 def restart(self):
     logSOLVER('restart')
     self.t = self.t0
     CE = FiniteElement('CG', cellShapes[self.dim - 1], self.degree)
     CS = FunctionSpace(self.mesh, CE)  # scalar space
     coords = gather_dof_coords(CS)
     logSOLVER('function_interpolate(self.U0, self.SS, coords=coords)',
               function_interpolate(self.U0, self.SS, coords=coords))
     fe.assign(self.sol.sub(1),
               function_interpolate(self.U0, self.SS, coords=coords))
     logSOLVER('U0 assign returned')
     fe.assign(self.sol.sub(0),
               function_interpolate(self.rho0, self.SS, coords=coords))
示例#5
0
 def restart(self):
     logPERIODIC('restart')
     self.t = self.t0
     U0comps = [None] * self.nligands * 2**self.dim
     for i, U0i in enumerate(self.U0s):
         eofuncs = evenodd_functions(omesh=self.omesh,
                                     degree=self.degree,
                                     func=U0i,
                                     evenodd=self.symmetries,
                                     width=self.xmax)
         U0comps[i * 2**self.dim:(i + 1) * 2**self.dim] = eofuncs
     rho0comps = evenodd_functions(omesh=self.omesh,
                                   degree=self.degree,
                                   func=self.rho0,
                                   evenodd=self.symmetries,
                                   width=self.xmax)
     coords = gather_dof_coords(rho0comps[0].function_space())
     for i in range(2**self.dim):
         fe.assign(
             self.sol.sub(i),
             function_interpolate(rho0comps[i], self.SS, coords=coords))
     for i in range(self.nligands * 2**self.dim):
         fe.assign(self.sol.sub(i + 2**self.dim),
                   function_interpolate(U0comps[i], self.SS, coords=coords))
示例#6
0
    def discretize(self):
        """Builds function space, call again after introducing constraints"""
        # FEniCS interface
        self.mesh = fn.IntervalMesh(self.N, self.x0_scaled, self.x1_scaled)

        # http://www.femtable.org/
        # Argyris*                          ARG
        # Arnold-Winther*                   AW
        # Brezzi-Douglas-Fortin-Marini*     BDFM
        # Brezzi-Douglas-Marini             BDM
        # Bubble                            B
        # Crouzeix-Raviart                  CR
        # Discontinuous Lagrange            DG
        # Discontinuous Raviart-Thomas      DRT
        # Hermite*                          HER
        # Lagrange                          CG
        # Mardal-Tai-Winther*               MTW
        # Morley*                           MOR
        # Nedelec 1st kind H(curl)          N1curl
        # Nedelec 2nd kind H(curl)          N2curl
        # Quadrature                        Q
        # Raviart-Thomas                    RT
        # Real                              R

        # construct test and trial function space from elements
        # spanned by Lagrange polynomials for the pyhsical variables of
        # potential and concentration and global elements with a single degree
        # of freedom ('Real') for constraints.
        # For an example of this approach, refer to
        #     https://fenicsproject.org/docs/dolfin/latest/python/demos/neumann-poisson/demo_neumann-poisson.py.html
        # For another example on how to construct and split function spaces
        # for solving coupled equations, refer to
        #     https://fenicsproject.org/docs/dolfin/latest/python/demos/mixed-poisson/demo_mixed-poisson.py.html

        P = fn.FiniteElement('Lagrange', fn.interval, 3)
        R = fn.FiniteElement('Real', fn.interval, 0)
        elements = [P] * (1 + self.M) + [R] * self.K

        H = fn.MixedElement(elements)
        self.W = fn.FunctionSpace(self.mesh, H)

        # solution functions
        self.w = fn.Function(self.W)

        # set initial values if available
        P = fn.FunctionSpace(self.mesh, 'P', 1)
        dof2vtx = fn.vertex_to_dof_map(P)
        if self.ui0 is not None:
            x = np.linspace(self.x0_scaled, self.x1_scaled, self.ui0.shape[0])
            ui0 = scipy.interpolate.interp1d(x, self.ui0)
            # use linear interpolation on mesh
            self.u0_func = fn.Function(P)
            self.u0_func.vector()[:] = ui0(self.X)[dof2vtx]
            fn.assign(self.w.sub(0),
                      fn.interpolate(self.u0_func,
                                     self.W.sub(0).collapse()))

        if self.ni0 is not None:
            x = np.linspace(self.x0_scaled, self.x1_scaled, self.ni0.shape[1])
            ni0 = scipy.interpolate.interp1d(x, self.ni0)
            self.p0_func = [fn.Function(P)] * self.ni0.shape[0]
            for k in range(self.ni0.shape[0]):
                self.p0_func[k].vector()[:] = ni0(self.X)[k, :][dof2vtx]
                fn.assign(
                    self.w.sub(1 + k),
                    fn.interpolate(self.p0_func[k],
                                   self.W.sub(k + 1).collapse()))

        # u represents voltage , p concentrations
        uplam = fn.split(self.w)
        self.u, self.p, self.lam = (uplam[0], [*uplam[1:(self.M + 1)]],
                                    [*uplam[(self.M + 1):]])

        # v, q and mu represent respective test functions
        vqmu = fn.TestFunctions(self.W)
        self.v, self.q, self.mu = (vqmu[0], [*vqmu[1:(self.M + 1)]],
                                   [*vqmu[(self.M + 1):]])
AA = fn.assemble(Left)
solver = fn.LUSolver(AA)
solver.parameters["reuse_factorization"] = True

# time loop
inc = 0

while (t <= T):

    print "t =", t

    # solve
    BB = fn.assemble(Right)
    solver.solve(Sol.vector(), BB)

    # output to file
    u, v = Sol.split()
    if (inc % frequencySave == 0):
        u.rename("u", "u")
        fileu << (u, t)
        v.rename("v", "v")
        filev << (v, t)

    # update old values
    fn.assign(uold, u)
    fn.assign(vold, v)

    # increment
    t += dt
    inc += 1
示例#8
0
 def up(self):
     if self.__up is None and self.__upv is not None:
         self.__up = fe.Function(V_up)
     fe.assign(self.__up.sub(0), self.__upv.sub(0))
     fe.assign(self.__up.sub(1), self.__upv.sub(1))
     return self.__up
示例#9
0
    def xest_implement_1d_myosin(self):
        #Parameters
        total_time = 10.0
        number_of_time_steps = 1000
        #         delta_t = fenics.Constant(total_time/number_of_time_steps)
        delta_t = total_time / number_of_time_steps
        nx = 1000
        domain_size = 1.0
        b = fenics.Constant(6.0)
        k = fenics.Constant(0.5)
        z_1 = fenics.Constant(-10.5)  #always negative
        #         z_1 = fenics.Constant(0.0) #always negative
        z_2 = 0.1  # always positive
        xi_0 = fenics.Constant(1.0)  #always positive
        xi_1 = fenics.Constant(1.0)  #always positive
        xi_2 = 0.001  #always positive
        xi_3 = 0.0001  #always negative
        d = fenics.Constant(0.15)
        alpha = fenics.Constant(1.0)
        c = fenics.Constant(0.1)

        # Sub domain for Periodic boundary condition
        class PeriodicBoundary(fenics.SubDomain):
            # Left boundary is "target domain" G
            def inside(self, x, on_boundary):
                return bool(-fenics.DOLFIN_EPS < x[0] < fenics.DOLFIN_EPS
                            and on_boundary)

            def map(self, x, y):
                y[0] = x[0] - 1

        periodic_boundary_condition = PeriodicBoundary()

        #Set up finite elements
        mesh = fenics.IntervalMesh(nx, 0.0, 1.0)
        vector_element = fenics.FiniteElement('P', fenics.interval, 1)
        single_element = fenics.FiniteElement('P', fenics.interval, 1)
        mixed_element = fenics.MixedElement(vector_element, single_element)
        V = fenics.FunctionSpace(
            mesh,
            mixed_element,
            constrained_domain=periodic_boundary_condition)
        #         V = fenics.FunctionSpace(mesh, mixed_element)
        v, r = fenics.TestFunctions(V)
        full_trial_function = fenics.Function(V)
        u, rho = fenics.split(full_trial_function)
        full_trial_function_n = fenics.Function(V)
        u_n, rho_n = fenics.split(full_trial_function_n)
        u_initial = fenics.Constant(0.0)
        #         rho_initial = fenics.Expression('1.0*sin(pi*x[0])*sin(pi*x[0])+1.0/k0', degree=2,k0 = k)
        rho_initial = fenics.Expression('1/k0', degree=2, k0=k)
        u_n = fenics.interpolate(u_initial, V.sub(0).collapse())
        rho_n = fenics.interpolate(rho_initial, V.sub(1).collapse())
        #         perturbation = np.zeros(rho_n.vector().size())
        #         perturbation[:int(perturbation.shape[0]/2)] = 1.0
        rho_n.vector().set_local(
            np.array(rho_n.vector()) + 1.0 *
            (0.5 - np.random.random(rho_n.vector().size())))
        #         u_n.vector().set_local(np.array(u_n.vector())+4.0*(0.5-np.random.random(u_n.vector().size())))
        fenics.assign(full_trial_function_n, [u_n, rho_n])
        u_n, rho_n = fenics.split(full_trial_function_n)

        F = (u * v * fenics.dx - u_n * v * fenics.dx + delta_t *
             (b + (z_1 * rho) /
              (1 + z_2 * rho) * c * xi_1) * u.dx(0) * v.dx(0) * fenics.dx -
             delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * xi_2 / 2.0 *
             u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx + delta_t * (z_1 * rho) /
             (1 + z_2 * rho) * c * c * c * xi_3 / 6.0 * u.dx(0) * u.dx(0) *
             u.dx(0) * v.dx(0) * fenics.dx - delta_t * z_1 * rho /
             (1 + z_2 * rho) * xi_0 * v.dx(0) * fenics.dx +
             u.dx(0) * v.dx(0) * fenics.dx - u_n.dx(0) * v.dx(0) * fenics.dx +
             rho * r * fenics.dx - rho_n * r * fenics.dx -
             rho * u * r.dx(0) * fenics.dx + rho * u_n * r.dx(0) * fenics.dx +
             delta_t * d * rho.dx(0) * r.dx(0) * fenics.dx +
             delta_t * k * fenics.exp(alpha * u.dx(0)) * rho * r * fenics.dx -
             delta_t * r * fenics.dx + delta_t * c * u.dx(0) * r * fenics.dx)

        vtkfile_rho = fenics.File(
            os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d',
                         'solution_rho.pvd'))
        vtkfile_u = fenics.File(
            os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d',
                         'solution_u.pvd'))

        #         rho_0 = fenics.Expression(((('0.0'),('0.0'),('0.0')),('sin(x[0])')), degree=1 )
        #         full_trial_function_n = fenics.project(rho_0, V)
        #         print('initial u and rho')
        #         print(u_n.vector())
        #         print(rho_n.vector())

        time = 0.0
        not_initialised = True
        plt.figure()
        for time_index in range(number_of_time_steps):
            # Update current time
            time += delta_t
            # Compute solution
            fenics.solve(F == 0, full_trial_function)
            # Save to file and plot solution
            vis_u, vis_rho = full_trial_function.split()
            plt.subplot(311)
            fenics.plot(vis_u, color='blue')
            plt.ylim(-0.5, 0.5)
            plt.subplot(312)
            fenics.plot(-vis_u.dx(0), color='blue')
            plt.ylim(-2, 2)
            plt.title('actin density change')
            plt.subplot(313)
            fenics.plot(vis_rho, color='blue')
            plt.title('myosin density')
            plt.ylim(0, 7)
            plt.tight_layout()
            if not_initialised:
                animation_camera = celluloid.Camera(plt.gcf())
                not_initialised = False
            animation_camera.snap()
            print('time is')
            print(time)
            #             plt.savefig(os.path.join(os.path.dirname(__file__),'output','this_output_at_time_' + '{:04d}'.format(time_index) + '.png'))
            #             print('this u and rho')
            #             print(np.array(vis_u.vector()))
            #             print(np.array(vis_rho.vector()))
            #             vtkfile_rho << (vis_rho, time)
            #             vtkfile_u << (vis_u, time)
            full_trial_function_n.assign(full_trial_function)

        animation = animation_camera.animate()
        animation.save(
            os.path.join(os.path.dirname(__file__), 'output', 'myosin_1D.mp4'))
示例#10
0
def navierStokes(projectId, mesh, faceSets, boundarySets, config):

    log("Navier Stokes Analysis has started")

    # this is the default directory, when user request for download all files in this directory is being compressed and sent to the user
    resultDir = "./Results/"

    if len(config["steps"]) > 1:
        return "more than 1 step is not supported yet"

    # config is a dictionary containing all the user inputs for solver configurations
    t_init = 0.0
    t_final = float(config['steps'][0]["finalTime"])
    t_num = int(config['steps'][0]["iterationNo"])
    dt = ((t_final - t_init) / t_num)
    t = t_init

    #
    #  Viscosity coefficient.
    #
    nu = float(config['materials'][0]["viscosity"])
    rho = float(config['materials'][0]["density"])

    #
    #  Declare Finite Element Spaces
    # do not use triangle directly
    P2 = fn.VectorElement("P", mesh.ufl_cell(), 2)
    P1 = fn.FiniteElement("P", mesh.ufl_cell(), 1)
    TH = fn.MixedElement([P2, P1])
    V = fn.VectorFunctionSpace(mesh, "P", 2)
    Q = fn.FunctionSpace(mesh, "P", 1)
    W = fn.FunctionSpace(mesh, TH)

    #
    #  Declare Finite Element Functions
    #
    (u, p) = fn.TrialFunctions(W)
    (v, q) = fn.TestFunctions(W)
    w = fn.Function(W)
    u0 = fn.Function(V)
    p0 = fn.Function(Q)

    #
    # Macros needed for weak formulation.
    #
    def contract(u, v):
        return fn.inner(fn.nabla_grad(u), fn.nabla_grad(v))

    def b(u, v, w):
        return 0.5 * (fn.inner(fn.dot(u, fn.nabla_grad(v)), w) -
                      fn.inner(fn.dot(u, fn.nabla_grad(w)), v))

    # Define boundaries
    bcs = []
    for BC in config['BCs']:
        if BC["boundaryType"] == "wall":
            for edge in json.loads(BC["edges"]):
                bcs.append(
                    fn.DirichletBC(W.sub(0),
                                   fn.Constant((0.0, 0.0, 0.0)),
                                   boundarySets,
                                   int(edge),
                                   method='topological'))
        if BC["boundaryType"] == "inlet":
            vel = json.loads(BC['value'])
            for edge in json.loads(BC["edges"]):
                bcs.append(
                    fn.DirichletBC(W.sub(0),
                                   fn.Expression(
                                       (str(vel[0]), str(vel[1]), str(vel[2])),
                                       degree=2),
                                   boundarySets,
                                   int(edge),
                                   method='topological'))
        if BC["boundaryType"] == "outlet":
            for edge in json.loads(BC["edges"]):
                bcs.append(
                    fn.DirichletBC(W.sub(1),
                                   fn.Constant(float(BC['value'])),
                                   boundarySets,
                                   int(edge),
                                   method='topological'))

    f = fn.Constant((0.0, 0.0, 0.0))

    #  weak form NSE
    NSE = (1.0/dt)*fn.inner(u, v)*fn.dx + b(u0, u, v)*fn.dx + nu * \
        contract(u, v)*fn.dx - fn.div(v)*p*fn.dx + q*fn.div(u)*fn.dx
    LNSE = fn.inner(f, v) * fn.dx + (1. / dt) * fn.inner(u0, v) * fn.dx

    velocity_file = fn.XDMFFile(resultDir + "/vel.xdmf")
    pressure_file = fn.XDMFFile(resultDir + "/pressure.xdmf")
    velocity_file.parameters["flush_output"] = True
    velocity_file.parameters["functions_share_mesh"] = True
    pressure_file.parameters["flush_output"] = True
    pressure_file.parameters["functions_share_mesh"] = True
    #
    # code for projecting a boundary condition into a file for visualization
    #
    # for bc in bcs:
    #     bc.apply(w.vector())
    # fn.File("para_plotting/bc.pvd") << w.sub(0)

    for jj in range(0, t_num):
        t = t + dt
        # print('t = ' + str(t))
        A, b = fn.assemble_system(NSE, LNSE, bcs)
        fn.solve(A, w.vector(), b)
        # fn.solve(NSE==LNSE,w,bcs)
        fn.assign(u0, w.sub(0))
        fn.assign(p0, w.sub(1))
        # Save Solutions to Paraview File
        if (jj % 20 == 0):
            velocity_file.write(u0, t)
            pressure_file.write(p0, t)
            sendFile(projectId, resultDir + "vel.xdmf")
            sendFile(projectId, resultDir + "vel.h5")
            sendFile(projectId, resultDir + "pressure.xdmf")
            sendFile(projectId, resultDir + "pressure.h5")
            statusUpdate(projectId, "STARTED", {"progress": jj / t_num * 100})
示例#11
0
Reactions = vold/dt * w * fn.dx + f(vold, nold) * w * fn.dx \
            + nold/dt * m * dx + g(vold, nold) * m * fn.dx
    
# ************* Time loop ********
start = time.clock(); inc = 0

while (t <= Tfinal):
    
    print "t =", t
    
    # solve
    KR = Reactions + Istim(t)*w*dx 
    fn.solve(WeakKarma == KR, Ksol,
    	solver_parameters={'linear_solver':'bicgstab'})
    v, n = Ksol.split()
    
    # save solution
    if (inc % frequency == 0):
        v.rename("v","v"); filev << (v,t)
        n.rename("n","n"); filen << (n,t)
         
    # update
    fn.assign(vold, v); fn.assign(nold, n)
    
    # increment
    t += dt; inc += 1

# time elapsed   
print "Time elapsed: ", time.clock()-start
示例#12
0
    def v(self, val):
        self.__v = None
        self.__uv = None
        self.__pv = None

        fe.assign(self.__upv.sub(2), val)
示例#13
0
    def p(self, val):
        self.__p = None
        self.__up = None
        self.__pv = None

        fe.assign(self.__upv.sub(1), val)
示例#14
0
    def u(self, val):
        self.__u = None
        self.__up = None
        self.__uv = None

        fe.assign(self.__upv.sub(0), val)
示例#15
0
 def upv(self, val):
     self.reset()
     fe.assign(self.__upv, val)
    h_g.t = t
    
    # solution
    solution = fn.Function(Hh)
    
    # solve
    fn.solve(left_hand_side == right_hand_side,
             solution,
             boundary_conditions)
    
    # split
    u, phi, p = solution.split()
    
    # save if divisible by frequency
    if iteration % frequency == 0:
        u.rename("u", "u")
        phi.rename("phi", "phi")
        p.rename("p", "p")
        pvdU << (u, t)
        pvdPHI << (phi, t)
        pvdP << (p, t)
    
    # update solutions
    #fn.assign(u_old, u)
    fn.assign(phi_old, phi)
    fn.assign(p_old, p)
    
    # update time
    t += dt
    iteration += 1
示例#17
0
 def u(self):
     if self.__u is None and self.__upv is not None:
         self.__u = fe.Function(V_u)
     fe.assign(self.__u, self.__upv.sub(0))
     return self.__u
示例#18
0
 def p(self):
     if self.__p is None and self.__upv is not None:
         self.__p = fe.Function(V_p)
     fe.assign(self.__p, self.__upv.sub(1))
     return self.__p
    # solve reaction-diffusion
    fn.solve(rd_left_hand_side == rd_rhs_2,
             rd_solution)
    
    # split
    E, n = rd_solution.split()
    
    # save if divisible by frequency
    if iteration % frequency == 0:
        u.rename("u", "u")
        phi.rename("phi", "phi")
        p.rename("p", "p")
        E.rename("E", "E")
        n.rename("n", "n")
        pvdU << (u, t)
        pvdPHI << (phi, t)
        pvdP << (p, t)
        pvdE << (E, t)
        pvdN << (n, t)
    
    # update solutions
    fn.assign(u_old, u)
    fn.assign(phi_old, phi)
    fn.assign(p_old, p)
    fn.assign(E_old, E)
    fn.assign(n_old, n)
    
    # update time
    t += dt
    iteration += 1
示例#20
0
 def v(self):
     if self.__v is None and self.__upv is not None:
         self.__v = fe.Function(V_v)
     fe.assign(self.__v, self.__upv.sub(2))
     return self.__v
示例#21
0
    def solve(self):
        """Solves the state system.

		Returns
		-------
		states : list[dolfin.function.function.Function]
			The solution of the state system.
		"""

        if not self.has_solution:
            if self.initial_guess is not None:
                for j in range(self.form_handler.state_dim):
                    fenics.assign(self.states[j], self.initial_guess[j])

            if not self.form_handler.state_is_picard or self.form_handler.state_dim == 1:
                if self.form_handler.state_is_linear:
                    for i in range(self.form_handler.state_dim):
                        A, b = _assemble_petsc_system(
                            self.form_handler.state_eq_forms_lhs[i],
                            self.form_handler.state_eq_forms_rhs[i],
                            self.bcs_list[i])
                        _solve_linear_problem(
                            self.ksps[i], A, b, self.states[i].vector().vec(),
                            self.form_handler.state_ksp_options[i])
                        self.states[i].vector().apply('')

                else:
                    for i in range(self.form_handler.state_dim):
                        if self.initial_guess is not None:
                            fenics.assign(self.states[i],
                                          self.initial_guess[i])

                        self.states[i] = damped_newton_solve(
                            self.form_handler.state_eq_forms[i],
                            self.states[i],
                            self.bcs_list[i],
                            rtol=self.newton_rtol,
                            atol=self.newton_atol,
                            max_iter=self.newton_iter,
                            damped=self.newton_damped,
                            verbose=self.newton_verbose,
                            ksp=self.ksps[i],
                            ksp_options=self.form_handler.state_ksp_options[i])

            else:
                for i in range(self.maxiter + 1):
                    res = 0.0
                    for j in range(self.form_handler.state_dim):
                        res_j = fenics.assemble(
                            self.form_handler.state_picard_forms[j])

                        [
                            bc.apply(res_j)
                            for bc in self.form_handler.bcs_list_ad[j]
                        ]

                        if self.number_of_solves == 0 and i == 0:
                            self.newton_atols[j] = res_j.norm(
                                'l2') * self.newton_atol
                            if res_j.norm('l2') == 0.0:
                                self.newton_atols[j] = self.newton_atol

                        res += pow(res_j.norm('l2'), 2)

                    if res == 0:
                        break
                    res = np.sqrt(res)
                    if i == 0:
                        res_0 = res
                    if self.picard_verbose:
                        print('Iteration ' + str(i) + ': ||res|| (abs): ' +
                              format(res, '.3e') + '   ||res|| (rel): ' +
                              format(res / res_0, '.3e'))
                    if res / res_0 < self.rtol or res < self.atol:
                        break

                    if i == self.maxiter:
                        raise NotConvergedError(
                            'Picard iteration for the state system')

                    for j in range(self.form_handler.state_dim):
                        if self.initial_guess is not None:
                            fenics.assign(self.states[j],
                                          self.initial_guess[j])

                        # adapt tolerances so that a solution is possible
                        if not self.form_handler.state_is_linear:
                            self.ksps[j].setTolerances(
                                rtol=np.minimum(0.9 * res, 0.9) / 100,
                                atol=self.newton_atols[j] / 100)

                            self.states[j] = damped_newton_solve(
                                self.form_handler.state_eq_forms[j],
                                self.states[j],
                                self.bcs_list[j],
                                rtol=np.minimum(0.9 * res, 0.9),
                                atol=self.newton_atols[j],
                                max_iter=self.newton_iter,
                                damped=self.newton_damped,
                                verbose=self.newton_verbose,
                                ksp=self.ksps[j],
                                ksp_options=self.form_handler.
                                state_ksp_options[j])
                        else:
                            A, b = _assemble_petsc_system(
                                self.form_handler.state_eq_forms_lhs[j],
                                self.form_handler.state_eq_forms_rhs[j],
                                self.bcs_list[j])
                            _solve_linear_problem(
                                self.ksps[j], A, b,
                                self.states[j].vector().vec(),
                                self.form_handler.state_ksp_options[j])
                            self.states[j].vector().apply('')

            if self.picard_verbose and self.form_handler.state_is_picard:
                print('')
            self.has_solution = True
            self.number_of_solves += 1

        return self.states
    plt.figure()
    plt.scatter(qq[:, 0], qq[:, 1], c=zz)
    plt.title('zz')

    #### Test vector function space ####

    V_vec = fenics.VectorFunctionSpace(V.mesh(),
                                       V.ufl_element().family(),
                                       V.ufl_element().degree())
    f = fenics.Function(V_vec)

    f0 = fenics.interpolate(
        fenics.Expression('sin(x[0]) + cos(x[1])', element=V.ufl_element()), V)
    f1 = fenics.interpolate(
        fenics.Expression('cos(x[0]) + sin(x[1])', element=V.ufl_element()), V)
    fenics.assign(f.sub(0), f0)
    fenics.assign(f.sub(1), f1)
    f.set_allow_extrapolation(True)

    t = time()
    eval_f = FenicsFunctionFastGridEvaluator(f)
    dt_construct_grid_evaluator = time() - t
    print('dt_construct_grid_evaluator=', dt_construct_grid_evaluator)

    n_test = int(1e4)
    qq = np.random.rand(n_test, d)
    qq = qq[np.linalg.norm(qq - 0.5, axis=1) < 0.5]
    n_test = qq.shape[0]
    t = time()
    zz = eval_f(qq)
    dt_interpn_vec = time() - t