Chapter 2
Design of the ode solver program

This gives high level view of my differential equations solver program which is in development for academic use. The program design is based on top-down modular design.

There are a number of public API’s. The main API is dsolve(). But there are other API’s such as for finding eigenvalues and eigenvectors.

This diagram shows the top level design

The following is the pseudo code of the dsolve() procedure. This is one of main calls into the main module for solving a single differential equation. It returns back all solutions found.

dsolve:=proc(ode,y(x),IC,hint::string) 
 
-- This CALL validates the ode itself. IC are validated by each separate 
-- module below this throws parse error if any fail 
ode_MGR:-parse_ode(ode); 
parse_IC_mgr:-parse_IC(ode,func,IC); 
 
IF hint is given THEN 
   IF ode_order =1 THEN 
      latex,solver_name,solution := first_order_ode_solver(ode,y(x),IC,hint); 
   ELIF  ode_order =2 THEN 
      latex,solver_name,solution := second_order_ode_solver(ode,y(x),IC,hint); 
   ELSE 
       ERROR; -- hint is only now supported for first and second order, not higher 
   END IF; 
 
ELSE -- no hint 
     -- the following factors ode if possible. For example for y''*y'=0 gives 
     -- y''=0 and y'=0 factors. If not possible to factor, ode itself is only 
     -- factor. in 99% of the times, ode do not factor and ode_factors list 
     -- will just contain the original ode. But this makes it much easier 
     -- to solve an ode if it can be factored. 
 
    ode_factors := factor_ode(ode); 
    FOR each factor DO 
        IF ode_order=1 THEN 
           latex,solver_name,solution := first_order_ode_solver(factor,y(x),IC,""); 
        ELIF ode_order=2 THEN 
           latex,solver_name,solution := second_order_ode_solver(factor,y(x),IC,""); 
        ELSE 
           latex,solver_name,solution := higher_order_ode_solver(factor,y(x),IC,""); 
        END IF; 
    END LOOP; 
END IF; 
 
RETURN latex, solver_used, solution; 
END proc;
 

The following is the main module for first order ode. Similar one for second order and similar one for higher order.

first_order_ode_solver:=proc(ode,y(x),IC,hint) 
 
    IF hint is given THEN 
       latex,solution := CALL the solver given in hit(ode,y(x),IC); 
    ELSE 
        -- check the ode type and call the lower level solver to solve it. 
        IF first_order_ode_quadrature:-is_quadrature(ode,y(x)) THEN 
            solutions := first_order_ode_quadrature:-dsolve(ode,y(x),IC); 
            solutions := FIRST_ORDER_POST_PROCESS(solutions,ode,y(x),IC); 
            IF list of solution not empty THEN 
               RETURN solutions --done 
            END IF 
        END IF 
 
        IF first_order_linear:-is_linear(ode,y(x)) THEN 
            solution := first_order_ode_linear:-dsolve(ode,y(x),IC); 
            solution := FIRST_ORDER_POST_PROCESS(solution,ode,y(x),IC); 
            IF list of solution not empty THEN 
               RETURN solutions --done 
            END IF 
        END IF 
 
        IF ... same for all other first order solvers. There are 16 solvers now. 
        . 
        . 
        . 
    END IF 
 
END proc;
 

The following is the post processing function for first order, called after each specific solver have generated the solutions.

 
FIRST_ORDER_POST_PROCESS:=proc(solutions,ode,y(x),IC) 
-- This is called after each specific found the solution. 
-- Each solver only find the solution and it does not do anything else. 
-- it takes as input list of solutions found, and returns list of solutions 
-- after post processing. 
 
    IF initial condition are given THEN 
        FOR each solution found DO 
            Update solution for initial conditions (this resolves constant of integration) 
        END LOOP 
    END IF 
 
    FOR each solution DO 
        IF solution is implicit then convert to explicit if possible and if solution 
           remains valid against the ode and IC's if any. This means the solution 
           if not already explicit, can remain implicit. 
        END IF 
    END LOOP 
 
    FOR each solution DO 
        Verify solution using odetest. 
        IF not verified THEN 
           remove solution. 
        END IF 
    END LOOP 
 
    RETURN solutions (this could be empty list if solution(s) could not be verified.) 
 
END proc;