Example #1
0
    def linear_solve(self):
        """
        Solve Ax = b with numpy and also with removal of uneccesary rows
        using the spaces object
        """
        timings.startnext("Numpy linear solve")
        info("Numpy Linear Solve")
        dofs = self.problem.spaces.usefuldofs

        #Original np array
        b = -self.F.array()
        #New np array
        b_np = b[dofs]
        #Solve the system
        x_np = np.linalg.solve(self.J_np, b_np)

        #map the solution back to the bigger space
        x = np.zeros(len(b))
        x[dofs] = x_np

        ##        #Create a Vector
        x_vec = Vector(len(x))
        x_vec[:] = x
        ##
        self.inc.vector()[:] = x
        timings.stop("Numpy linear solve")
Example #2
0
    def linear_solve(self):
        """
        Solve Ax = b with numpy and also with removal of uneccesary rows
        using the spaces object
        """
        timings.startnext("Numpy linear solve")
        info("Numpy Linear Solve")
        dofs = self.problem.spaces.usefuldofs

        #Original np array
        b = -self.F.array()
        #New np array
        b_np = b[dofs]
        #Solve the system
        x_np = np.linalg.solve(self.J_np,b_np)

        #map the solution back to the bigger space
        x = np.zeros(len(b))
        x[dofs] = x_np

##        #Create a Vector
        x_vec = Vector(len(x))
        x_vec[:] = x
##        
        self.inc.vector()[:] = x
        timings.stop("Numpy linear solve")
Example #3
0
    def build_jacobian(self):
        """Assemble Jacobian"""
        info("Assembling Jacobian")
        
        #If buffered matrix add the variable part to the buffered part.
        if self.problem.J_buff is not None:
            timings.startnext("Copy Buffered Jacobian")
            self.J = self.problem.J_buff.copy()

            timings.startnext("Jacobian Assembly")
            self.J = assemble(self.problem.j, tensor = self.J,
                              cell_domains = self.problem.cell_domains,
                              interior_facet_domains = self.problem.interior_facet_domains,
                              exterior_facet_domains = self.problem.exterior_facet_domains,
                              reset_sparsity = False,
                              add_values = True,
                              form_compiler_parameters = self.ffc_opt)
            timings.stop("Jacobian Assembly")
        else:
            #No buffering just assemble
            timings.startnext("Jacobian Assembly")
            self.J = assemble(self.problem.j, tensor = self.J,
                              cell_domains = self.problem.cell_domains,
                              interior_facet_domains = self.problem.interior_facet_domains,
                              exterior_facet_domains = self.problem.exterior_facet_domains,
                              form_compiler_parameters = self.ffc_opt)
            timings.stop("Jacobian Assembly")
        #Give the Jacobian it's BC.
        self.apply_ident_bc()
        #Create an LU Solver
        # Create linear solver and factorize matrix
        self.linsolver = LUSolver(self.J)
        self.linsolver.parameters["reuse_factorization"] = True
Example #4
0
 def build_residual(self):
     """Assemble Residual"""
     timings.startnext("Residual assembly")
     info("Residual Assembly")
     self.F = assemble(self.problem.f, tensor = self.F,
          cell_domains = self.problem.cell_domains,
          interior_facet_domains = self.problem.interior_facet_domains,
          exterior_facet_domains = self.problem.exterior_facet_domains)
     [bc.apply(self.F) for bc in self.problem.bc]
     timings.stop("Residual assembly")
Example #5
0
 def assemble_J_buff(self):
     """Assembles the buffered jacobian"""
     info("Assembling Buffered Jacobian")
     timings.startnext("Buffered Jacobian assembly")
     J_buff = assemble(self.j_buff,
                       cell_domains = self.problem.meshfunctions["cell"],
                       interior_facet_domains = self.problem.meshfunctions["interiorfacet"],
                       exterior_facet_domains = self.problem.meshfunctions["exteriorfacet"]  )
     timings.stop("Buffered Jacobian assembly")
     return J_buff
Example #6
0
 def assemble_J_buff(self):
     """Assembles the buffered jacobian"""
     info("Assembling Buffered Jacobian")
     timings.startnext("Buffered Jacobian assembly")
     J_buff = assemble(self.j_buff,
                       cell_domains = self.problem.cellfunc,
                       interior_facet_domains = self.problem.fsiboundfunc,
                       exterior_facet_domains = self.problem.extboundfunc)
     timings.stop("Buffered Jacobian assembly")
     return J_buff
Example #7
0
 def build_residual(self):
     """Assemble Residual"""
     timings.startnext("Residual assembly")
     info("Residual Assembly")
     self.F = assemble(
         self.problem.f,
         tensor=self.F,
         cell_domains=self.problem.cell_domains,
         interior_facet_domains=self.problem.interior_facet_domains,
         exterior_facet_domains=self.problem.exterior_facet_domains)
     [bc.apply(self.F) for bc in self.problem.bc]
     timings.stop("Residual assembly")
Example #8
0
    def __init__(self,problem,params = fsinewton_params):
        
        timings.startnext("Fsi Newton Solver init")
        info_blue("Initializing FSI Newton Solver")
        info("Using params \n" + str(params) )
        #Initialize base class
        ccom.CBCSolver.__init__(self)
        self.problem = problem
        self.params = params
        #Define the various helper objects of the fsinewton solver
        self.spaces = FSISpaces(problem,params)
        self.fsibc = FSIBC(problem,self.spaces)

        #Define mixed Functions
        self.U0 = self.__initial_state()
        self.U1 = Function(self.spaces.fsispace)

        #Define Subfunction references to the mixed functions
        (self.U1_F,self.P1_F,self.L1_U,self.D1_S,self.U1_S,self.D1_F,self.L1_D) = self.U1.split()
        (self.U0_F,self.P0_F,self.L0_U,self.D0_S,self.U0_S,self.D0_F,self.L0_D) = self.U0.split()

        #Define list tensor references to the mixed funtions
        self.U1list = self.spaces.unpack_function(self.U1)
        self.U0list = self.spaces.unpack_function(self.U0)

        #Define Mixed Trial and Test Functions
        self.IU = TrialFunctions(self.spaces.fsispace)
        self.V = TestFunctions(self.spaces.fsispace)

        #Define time relevant variables
        self.dt = self.problem.initial_step()
        self.kn = Constant(self.dt)
        self.t = 0.0
        
        #Define Time Descretized Functions
        self.Umid,self.Udot = self.time_discreteU(self.U1list,self.U0list,self.kn)
        self.IUmid,self.IUdot = self.time_discreteI(self.IU,self.kn)
        
        #Initialize any Body forces if present
        self.__init_forces()

        #Define Forms and buffered part of the jacobian matrix.
        self.r,self.j,self.j_buff = self.create_forms()
        self.runtimedata = FsiRunTimeData(self)
        timings.stop("Fsi Newton Solver init")
Example #9
0
    def build_jacobian(self):
        """Assemble Jacobian"""
        info("Assembling Jacobian")

        #If buffered matrix add the variable part to the buffered part.
        if self.problem.J_buff is not None:
            timings.startnext("Copy Buffered Jacobian")
            self.J = self.problem.J_buff.copy()

            timings.startnext("Jacobian Assembly")
            self.J = assemble(
                self.problem.j,
                tensor=self.J,
                cell_domains=self.problem.cell_domains,
                interior_facet_domains=self.problem.interior_facet_domains,
                exterior_facet_domains=self.problem.exterior_facet_domains,
                reset_sparsity=False,
                add_values=True,
                form_compiler_parameters=self.ffc_opt)
            timings.stop("Jacobian Assembly")
        else:
            #No buffering just assemble
            timings.startnext("Jacobian Assembly")
            self.J = assemble(
                self.problem.j,
                tensor=self.J,
                cell_domains=self.problem.cell_domains,
                interior_facet_domains=self.problem.interior_facet_domains,
                exterior_facet_domains=self.problem.exterior_facet_domains,
                form_compiler_parameters=self.ffc_opt)
            timings.stop("Jacobian Assembly")
        #Give the Jacobian it's BC.
        self.apply_ident_bc()
        #Create an LU Solver
        # Create linear solver and factorize matrix
        self.linsolver = LUSolver(self.J)
        self.linsolver.parameters["reuse_factorization"] = True
Example #10
0
 def linear_solve(self):
     """Dolfin/PETSc linear solve"""
     timings.startnext("PETSc linear solve")
     info("PETSc Linear Solve")
     self.linsolver.solve(self.inc.vector(),-self.F)        
     timings.stop("PETSc linear solve")         
Example #11
0
 def linear_solve(self):
     """Dolfin/PETSc linear solve"""
     timings.startnext("PETSc linear solve")
     info("PETSc Linear Solve")
     self.linsolver.solve(self.inc.vector(), -self.F)
     timings.stop("PETSc linear solve")
Example #12
0
    def solve_primal(self, problem, parameters):
        "Solve primal FSI problem"
        #def __init__()
        # Get parameters
        T = problem.end_time()
        dt = initial_timestep(problem, parameters)
        TOL = parameters["tolerance"]
        w_k = parameters["w_k"]
        w_c = parameters["w_c"]
        save_solution = parameters["save_solution"]
        uniform_timestep = parameters["uniform_timestep"]
        plot_solution = parameters["plot_solution"]

        # Create files for saving to VTK
        level = refinement_level()
        if save_solution:
            files = (File("%s/pvd/level_%d/u_F.pvd" %
                          (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/p_F.pvd" %
                          (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/U_S.pvd" %
                          (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/P_S.pvd" %
                          (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/U_M.pvd" %
                          (parameters["output_directory"], level)))

        # Create time series for storing solution
        primal_series = create_primal_series(parameters)

        # Create time series for dual solution
        if level > 0:
            dual_series = create_dual_series(parameters)
        else:
            dual_series = None

        # Record CPU time
        cpu_time = python_time()

        # Record number of time steps
        timestep_counter = 0

        # Update of user problem at t = 0 (important for initial conditions)
        problem.update(0.0, 0.0, dt)

        # Define the three subproblems
        F = FluidProblem(problem, solver_type=parameters["fluid_solver"])
        S = StructureProblem(problem, parameters)
        M = MeshProblem(problem, parameters)

        # Get solution values
        u_F0, u_F1, p_F0, p_F1 = F.solution_values()
        U_M0, U_M1 = M.solution_values()

        # Extract number of dofs
        num_dofs_FSM = extract_num_dofs(F, S, M)
        info("FSI problem has %d dofs (%d + %d + %d)" % \
            (num_dofs_FSM, F.num_dofs, S.num_dofs, M.num_dofs))

        # Get initial structure displacement (used for plotting and checking convergence)
        structure_element_degree = parameters["structure_element_degree"]
        V_S = VectorFunctionSpace(problem.structure_mesh(), "CG",
                                  structure_element_degree)
        U_S0 = Function(V_S)

        # Save initial solution to file and series
        U = extract_solution(F, S, M)
        if save_solution:
            _save_solution(U, files)
            write_primal_data(U, 0, primal_series)

        # Initialize adaptive data
        init_adaptive_data(problem, parameters)

        # Initialize time-stepping
        t0 = 0.0
        t1 = dt
        at_end = abs(t1 - T) / T < 100.0 * DOLFIN_EPS

        # Initialize integration of goal functional (assuming M(u) = 0 at t = 0)
        integrated_goal_functional = 0.0
        old_goal_functional = 0.0

        # Get reference value of goal functional
        if hasattr(problem, "reference_value"):
            reference_value = problem.reference_value()
        else:
            reference_value = None

        if parameters["primal_solver"] == "Newton":
            #If no initial_step function try to generate one
            if not hasattr(problem, "initial_step"):
                problem.initial_step = lambda: parameters["initial_timestep"]

            # Initialize an FSINewtonSolver Object
            fsinewtonsolver = FSINewtonSolver(problem,\
                                params = parameters["FSINewtonSolver"].to_dict())

            #initialize the solve settings
            fsinewtonsolver.prepare_solve()

        #def solve_primal()
        while True:

            # Display progress
            info("")
            info("-" * 80)
            begin("* Starting new time step")
            info_blue("  * t = %g (T = %g, dt = %g)" % (t1, T, dt))

            # Update of user problem
            problem.update(t0, t1, dt)

            # Compute tolerance for FSI iterations
            itertol = compute_itertol(problem, w_c, TOL, dt, t1, parameters)
            if parameters["primal_solver"] == "Newton":
                #Newtonsolver has it's own timings
                assert save_solution, "Parameter save_solution must be true to use the Newton Solver"
                U_S1, U_S0, P_S1, increment, numiter = newton_solve(
                    F, S, M, U_S0, dt, parameters, itertol, problem,
                    fsinewtonsolver)
            elif parameters["primal_solver"] == "fixpoint":
                timings.startnext("FixpointSolve")
                U_S0, U_S1, P_S1, increment, numiter = fixpoint_solve(
                    F, S, U_S0, M, dt, t1, parameters, itertol, problem)
                timings.stop("FixpointSolve")
            else:
                raise Exception(
                    "Only 'fixpoint' and 'Newton' are possible values \
                                for the parameter 'primal_solver'")
            self.g_numiter = numiter
            #####################################################
            #The primal solve worked so now go to post processing
            #####################################################
            #def postprocessing():
            # Plot solution
            if plot_solution:
                _plot_solution(u_F1, p_F1, U_S0, U_M1)
            if problem.exact_solution() is not None:
                update_exactsol(u_F1, p_F1, U_S1, U_M1, F, problem, t1)

            info("")
            info_green(
                "Increment = %g (tolerance = %g), converged after %d iterations"
                % (increment, itertol, numiter + 1))
            info("")
            end()

            # Saving number of FSI iterations
            save_no_FSI_iter(t1, numiter + 1, parameters)

            # Evaluate user goal functional
            goal_functional = assemble(
                problem.evaluate_functional(u_F1, p_F1, U_S1, P_S1, U_M1, dx,
                                            dx, dx))

            # Integrate goal functional
            integrated_goal_functional += 0.5 * dt * (old_goal_functional +
                                                      goal_functional)
            old_goal_functional = goal_functional

            # Save goal functional
            save_goal_functional(t1, goal_functional,
                                 integrated_goal_functional, parameters)

            # Save solution and time series to file
            U = extract_solution(F, S, M)
            if save_solution:
                _save_solution(U, files)
                write_primal_data(U, t1, primal_series)

            # Move to next time step
            F.update(t1)
            S.update()
            M.update(t1)

            # Update time step counter
            timestep_counter += 1

            # FIXME: This should be done automatically by the solver
            F.update_extra()

            # Check if we have reached the end time
            if at_end:
                info("")
                info_green("Finished time-stepping")
                save_dofs(num_dofs_FSM, timestep_counter, parameters)
                end()
                break

            # Use constant time step
            if uniform_timestep:
                t0 = t1
                t1 = min(t1 + dt, T)
                dt = t1 - t0
                at_end = abs(t1 - T) / T < 100.0 * DOLFIN_EPS

            # Compute new adaptive time step
            else:
                Rk = compute_time_residual(primal_series, dual_series, t0, t1,
                                           problem, parameters)
                (dt, at_end) = compute_time_step(problem, Rk, TOL, dt, t1, T,
                                                 w_k, parameters)
                t0 = t1
                t1 = t1 + dt
        #End of Time loop
        #Call post processing for the Newton Solver if necessary.
        if parameters["primal_solver"] == "Newton":
            fsinewtonsolver.post_processing()
        # Save final value of goal functional
        save_goal_functional_final(goal_functional, integrated_goal_functional,
                                   reference_value, parameters)

        # Report elapsed time
        info_blue("Primal solution computed in %g seconds." %
                  (python_time() - cpu_time))
        info("")

        # Return solution
        info(timings.report_str())
        return (goal_functional, integrated_goal_functional)
Example #13
0
    def solve_primal(self,problem, parameters):
        "Solve primal FSI problem"
        #def __init__()
        # Get parameters
        T = problem.end_time()
        dt = initial_timestep(problem, parameters)
        TOL = parameters["tolerance"]
        w_k = parameters["w_k"]
        w_c = parameters["w_c"]
        save_solution = parameters["save_solution"] 
        uniform_timestep = parameters["uniform_timestep"]
        plot_solution = parameters["plot_solution"]

        # Create files for saving to VTK
        level = refinement_level()
        if save_solution:
            files = (File("%s/pvd/level_%d/u_F.pvd" % (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/p_F.pvd" % (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/U_S.pvd" % (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/P_S.pvd" % (parameters["output_directory"], level)),
                     File("%s/pvd/level_%d/U_M.pvd" % (parameters["output_directory"], level)))

        # Create time series for storing solution
        primal_series = create_primal_series(parameters)

        # Create time series for dual solution
        if level > 0:
            dual_series = create_dual_series(parameters)
        else:
            dual_series = None

        # Record CPU time
        cpu_time = python_time()

        # Record number of time steps
        timestep_counter = 0

        # Update of user problem at t = 0 (important for initial conditions)
        problem.update(0.0, 0.0, dt)

        # Define the three subproblems
        F = FluidProblem(problem, solver_type=parameters["fluid_solver"])
        S = StructureProblem(problem, parameters)
        M = MeshProblem(problem, parameters)

        # Get solution values
        u_F0, u_F1, p_F0, p_F1 = F.solution_values()
        U_M0, U_M1 = M.solution_values()

        # Extract number of dofs
        num_dofs_FSM = extract_num_dofs(F, S, M)
        info("FSI problem has %d dofs (%d + %d + %d)" % \
            (num_dofs_FSM, F.num_dofs, S.num_dofs, M.num_dofs))

        # Get initial structure displacement (used for plotting and checking convergence)
        structure_element_degree = parameters["structure_element_degree"]
        V_S = VectorFunctionSpace(problem.structure_mesh(), "CG", structure_element_degree)
        U_S0 = Function(V_S)

        # Save initial solution to file and series
        U = extract_solution(F, S, M)
        if save_solution:
            _save_solution(U, files)
            write_primal_data(U, 0, primal_series)

        # Initialize adaptive data
        init_adaptive_data(problem, parameters)

        # Initialize time-stepping
        t0 = 0.0
        t1 = dt
        at_end = abs(t1 - T) / T < 100.0*DOLFIN_EPS

        # Initialize integration of goal functional (assuming M(u) = 0 at t = 0)
        integrated_goal_functional = 0.0
        old_goal_functional = 0.0

        # Get reference value of goal functional
        if hasattr(problem, "reference_value"):
            reference_value = problem.reference_value()
        else:
            reference_value = None

        if parameters["primal_solver"] == "Newton":
            #If no initial_step function try to generate one
            if not hasattr(problem,"initial_step"):
                problem.initial_step = lambda :parameters["initial_timestep"]
            
            # Initialize an FSINewtonSolver Object
            fsinewtonsolver = FSINewtonSolver(problem,\
                                params = parameters["FSINewtonSolver"].to_dict())

            #initialize the solve settings
            fsinewtonsolver.prepare_solve()
            
        #def solve_primal()
        while True:

            # Display progress
            info("")
            info("-"*80)
            begin("* Starting new time step")
            info_blue("  * t = %g (T = %g, dt = %g)" % (t1, T, dt))

            # Update of user problem
            problem.update(t0, t1, dt)

            # Compute tolerance for FSI iterations
            itertol = compute_itertol(problem, w_c, TOL, dt, t1, parameters)
            if parameters["primal_solver"] == "Newton":
                #Newtonsolver has it's own timings
                assert save_solution,"Parameter save_solution must be true to use the Newton Solver"
                U_S1,U_S0,P_S1,increment,numiter = newton_solve(F,S,M,U_S0,dt,parameters,itertol,problem,fsinewtonsolver)
            elif parameters["primal_solver"] == "fixpoint":
                timings.startnext("FixpointSolve")
                U_S0,U_S1,P_S1,increment,numiter = fixpoint_solve(F,S,U_S0,M,dt,t1,parameters,itertol,problem)
                timings.stop("FixpointSolve")
            else:
                raise Exception("Only 'fixpoint' and 'Newton' are possible values \
                                for the parameter 'primal_solver'")
            self.g_numiter = numiter
        #####################################################
        #The primal solve worked so now go to post processing
        #####################################################
        #def postprocessing():
            # Plot solution
            if plot_solution:
                _plot_solution(u_F1, p_F1, U_S0, U_M1)
            if problem.exact_solution() is not None:
                update_exactsol(u_F1,p_F1,U_S1,U_M1,F,problem,t1)      

            info("")
            info_green("Increment = %g (tolerance = %g), converged after %d iterations" % (increment, itertol, numiter + 1))
            info("")
            end()

            # Saving number of FSI iterations
            save_no_FSI_iter(t1, numiter + 1, parameters)

            # Evaluate user goal functional
            goal_functional = assemble(problem.evaluate_functional(u_F1, p_F1, U_S1, P_S1, U_M1, dx, dx, dx))

            # Integrate goal functional
            integrated_goal_functional += 0.5 * dt * (old_goal_functional + goal_functional)
            old_goal_functional = goal_functional

            # Save goal functional
            save_goal_functional(t1, goal_functional, integrated_goal_functional, parameters)


            # Save solution and time series to file
            U = extract_solution(F, S, M)
            if save_solution:
                _save_solution(U, files)
                write_primal_data(U, t1, primal_series)

            # Move to next time step
            F.update(t1)
            S.update()
            M.update(t1)

            # Update time step counter
            timestep_counter += 1

            # FIXME: This should be done automatically by the solver
            F.update_extra()

            # Check if we have reached the end time
            if at_end:
                info("")
                info_green("Finished time-stepping")
                save_dofs(num_dofs_FSM, timestep_counter, parameters)
                end()
                break

            # Use constant time step
            if uniform_timestep:
                t0 = t1
                t1 = min(t1 + dt, T)
                dt = t1 - t0
                at_end = abs(t1 - T) / T < 100.0*DOLFIN_EPS

            # Compute new adaptive time step
            else:
                Rk = compute_time_residual(primal_series, dual_series, t0, t1, problem, parameters)
                (dt, at_end) = compute_time_step(problem, Rk, TOL, dt, t1, T, w_k, parameters)
                t0 = t1
                t1 = t1 + dt
        #End of Time loop
        #Call post processing for the Newton Solver if necessary.
        if parameters["primal_solver"] == "Newton":
            fsinewtonsolver.post_processing()
        # Save final value of goal functional
        save_goal_functional_final(goal_functional, integrated_goal_functional, reference_value, parameters)

        # Report elapsed time
        info_blue("Primal solution computed in %g seconds." % (python_time() - cpu_time))
        info("")

        # Return solution
        info(timings.report_str())
        return (goal_functional, integrated_goal_functional)