Repository: qutip/qutip

Issue:
documentation for the use of superoperators in `mesolve`s `c_ops`
I did not see this documented so I had to go through the actual code:
- Is it officially supported to use superoperators for collapse operators in `mesolve`?
- There seems to be some difference whether the operator is quared or not... What is the canonical form used in `qutip`?



Discussion:
Hi. Yes, it is officially supported to use superoperators instead of collapse operators. The following should all be identical:

```
N = 10
kappa = 0.5
a = destroy(10)
H = a.dag() * a
psi = basis(N, 5)
times = np.linspace(0, 10, 100)
e_ops = [a.dag() * a, a + a.dag()]
args = {'kappa': kappa}
result1 = mesolve(H, psi, times, [a * np.sqrt(kappa)], e_ops, args=args)
result2 = mesolve(H, psi, times, [liouvillian(None, [a * np.sqrt(kappa)])], e_ops, args=args)
result3 = mesolve(H, psi, times, [[a, 'sqrt(kappa)']], e_ops, args=args)
result4 = mesolve(H, psi, times, [[liouvillian(None, [a]), 'kappa']], e_ops, args=args)
```


Resolving patch:
diff --git a/qutip/mesolve.py b/qutip/mesolve.py
--- a/qutip/mesolve.py
+++ b/qutip/mesolve.py
@@ -59,7 +59,7 @@
 from qutip.sesolve import (_sesolve_list_func_td, _sesolve_list_str_td,
                            _sesolve_list_td, _sesolve_func_td, _sesolve_const)
 
-from qutip.ui.progressbar import BaseProgressBar
+from qutip.ui.progressbar import BaseProgressBar, TextProgressBar
 
 if debug:
     import inspect
@@ -70,13 +70,14 @@
 # any collapse operators were given.
 #
 def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None,
-            progress_bar=BaseProgressBar()):
+            progress_bar=None):
     """
-    Master equation evolution of a density matrix for a given Hamiltonian.
+    Master equation evolution of a density matrix for a given Hamiltonian and
+    set of collapse operators, or a Liouvillian.
 
     Evolve the state vector or density matrix (`rho0`) using a given
     Hamiltonian (`H`) and an [optional] set of collapse operators
-    (`c_op_list`), by integrating the set of ordinary differential equations
+    (`c_ops`), by integrating the set of ordinary differential equations
     that define the system. In the absence of collapse operators the system is
     evolved according to the unitary evolution of the Hamiltonian.
 
@@ -86,6 +87,12 @@ def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None,
     time in `tlist` with time and the state as arguments, and the function
     does not use any return values.
 
+    If either `H` or the Qobj elements in `c_ops` are superoperators, they
+    will be treated as direct contributions to the total system Liouvillian.
+    This allows to solve master equations that are not on standard Lindblad
+    for by passing a custom Liouvillian in place of either `H` or `c_ops`
+    elements.
+
     **Time-dependent operators**
 
     For problems with time-dependent problems `H` and `c_ops` can be callback
@@ -102,23 +109,26 @@ def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None,
     array format*) which specifies the value of the coefficient to the
     corresponding operator for each value of t in tlist.
 
+    Yet another alternative is to specify the time dependence using NumPy
+    arrays with the same length as the `tlist` array (*list array format*).
+
     *Examples*
 
         H = [[H0, 'sin(w*t)'], [H1, 'sin(2*w*t)']]
 
-        H = [[H0, sin(w*tlist)], [H1, sin(2*w*tlist)]]
-
         H = [[H0, f0_t], [H1, f1_t]]
 
         where f0_t and f1_t are python functions with signature f_t(t, args).
 
+        H = [[H0, np.sin(w*tlist)], [H1, np.sin(2*w*tlist)]]
+
     In the *list string format* and *list callback format*, the string
     expression and the callback function must evaluate to a real or complex
     number (coefficient for the corresponding operator).
 
     In all cases of time-dependent operators, `args` is a dictionary of
     parameters that is used when evaluating operators. It is passed to the
-    callback functions as second argument
+    callback functions as second argument.
 
     .. note::
 
@@ -144,8 +154,8 @@ def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None,
     ----------
 
     H : :class:`qutip.Qobj`
-        system Hamiltonian, or a callback function for time-dependent
-        Hamiltonians.
+        System Hamiltonian, or a callback function for time-dependent
+        Hamiltonians, or alternatively a system Liouvillian.
 
     rho0 : :class:`qutip.Qobj`
         initial density matrix or state vector (ket).
@@ -154,7 +164,8 @@ def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None,
         list of times for :math:`t`.
 
     c_ops : list of :class:`qutip.Qobj`
-        single collapse operator, or list of collapse operators.
+        single collapse operator, or list of collapse operators, or a list
+        of Liouvillian superoperators.
 
     e_ops : list of :class:`qutip.Qobj` / callback function single
         single operator or list of operators for which to evaluate
@@ -165,26 +176,31 @@ def mesolve(H, rho0, tlist, c_ops, e_ops, args={}, options=None,
         collapse operators.
 
     options : :class:`qutip.Options`
-        with options for the ODE solver.
+        with options for the solver.
 
-    progress_bar: TextProgressBar
+    progress_bar: BaseProgressBar
         Optional instance of BaseProgressBar, or a subclass thereof, for
         showing the progress of the simulation.
 
     Returns
     -------
 
-    output: :class:`qutip.solver`
+    result: :class:`qutip.Result`
 
-        An instance of the class :class:`qutip.solver`, which contains either
-        an *array* of expectation values for the times specified by `tlist`, or
-        an *array* or state vectors or density matrices corresponding to the
-        times in `tlist` [if `e_ops` is an empty list], or
-        nothing if a callback function was given in place of operators for
-        which to calculate the expectation values.
+        An instance of the class :class:`qutip.Result`, which contains
+        either an *array* `result.expect` of expectation values for the times
+        specified by `tlist`, or an *array* `result.states` of state vectors or
+        density matrices corresponding to the times in `tlist` [if `e_ops` is
+        an empty list], or nothing if a callback function was given in place of
+        operators for which to calculate the expectation values.
 
     """
 
+    if progress_bar is None:
+        progress_bar = BaseProgressBar()
+    elif progress_bar is True:
+        progress_bar = TextProgressBar()
+
     # check whether c_ops or e_ops is is a single operator
     # if so convert it to a list containing only that operator
     if isinstance(c_ops, Qobj):
@@ -642,7 +658,7 @@ def _mesolve_const(H, rho0, tlist, c_op_list, e_ops, args, opt,
                                   progress_bar)
 
         # Got a wave function as initial state: convert to density matrix.
-        rho0 = rho0 * rho0.dag()
+        rho0 = ket2dm(rho0)
 
     #
     # construct liouvillian


Test patch: