Skip to content
10 changes: 7 additions & 3 deletions include/hamiltonianfilereader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>
#include <assert.h>
#include <iostream>
#include <fstream>
#include <controlbasis.hpp>

#pragma once
Expand All @@ -20,8 +21,10 @@ class HamiltonianFileReader{

LindbladType lindbladtype; ///< Type of solver (Lindblad vs Schroedinger)
int dim_rho; ///< Dimension of the Hilbert space (N)
std::string hamiltonian_file; ///< Filename for Hamiltonian data ('none' if not used)
std::string hamiltonian_file_Hsys; ///< Filename for system Hamiltonian data ('none' if not used)
std::string hamiltonian_file_Hc; ///< Filename for control Hamiltonian data ('none' if not used)
int mpirank_world; ///< Rank of global MPI communicator
int mpisize_world; ///< Rank of global MPI communicator
bool quietmode; ///< Flag for quiet mode operation

public:
Expand All @@ -30,12 +33,13 @@ class HamiltonianFileReader{
/**
* @brief Constructor with Hamiltonian file specification.
*
* @param hamiltonian_file_ Path to file containing Hamiltonian data
* @param hamiltonian_file_Hsys Path to file containing system Hamiltonian data
* @param hamiltonian_file_Hc Path to file containing control Hamiltonian data
* @param lindbladtype_ Type of solver (Lindblad or Schroedinger)
* @param dim_rho_ Dimension of the Hilbert space
* @param quietmode_ Flag for quiet operation
*/
HamiltonianFileReader(std::string hamiltonian_file_, LindbladType lindbladtype_, int dim_rho_, bool quietmode_);
HamiltonianFileReader(std::string hamiltonian_file_Hsys, std::string hamiltonian_file_Hc, LindbladType lindbladtype_, int dim_rho_, bool quietmode_);

~HamiltonianFileReader();

Expand Down
8 changes: 5 additions & 3 deletions include/mastereq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ class MasterEq{
IS isu, isv; ///< Vector strides for accessing real and imaginary parts u=Re(x), v=Im(x)
Vec aux; ///< Auxiliary vector for computations
bool quietmode; ///< Flag for quiet mode operation
std::string hamiltonian_file; ///< Filename if a custom Hamiltonian is read from file ('none' if standard Hamiltonian is used)
std::string hamiltonian_file_Hsys; ///< Filename if a custom system Hamiltonian is read from file ('none' if standard Hamiltonian is used)
std::string hamiltonian_file_Hc; ///< Filename if a custom control Hamiltonians are read from file ('none' if standard Hamiltonian is used)

public:
std::vector<int> nlevels; ///< Number of levels per oscillator
Expand All @@ -137,10 +138,11 @@ class MasterEq{
* @param eta_ Frequency differences for rotating frame
* @param lindbladtype_ Type of Lindblad operators to include
* @param usematfree_ Flag to use matrix-free solver
* @param hamiltonian_file Filename for Hamiltonian data
* @param hamiltonian_file_Hsys Filename for Hamiltonian data
* @param hamiltonian_file_Hc Filename for Hamiltonian data
* @param quietmode Flag for quiet operation (default: false)
*/
MasterEq(const std::vector<int>& nlevels, const std::vector<int>& nessential, Oscillator** oscil_vec_, const std::vector<double>& crosskerr_, const std::vector<double>& Jkl_, const std::vector<double>& eta_, LindbladType lindbladtype_, bool usematfree_, const std::string& hamiltonian_file, bool quietmode=false);
MasterEq(const std::vector<int>& nlevels, const std::vector<int>& nessential, Oscillator** oscil_vec_, const std::vector<double>& crosskerr_, const std::vector<double>& Jkl_, const std::vector<double>& eta_, LindbladType lindbladtype_, bool usematfree_, const std::string& hamiltonian_file_Hsys, const std::string& hamiltonian_file_Hc, bool quietmode=false);

~MasterEq();

Expand Down
59 changes: 29 additions & 30 deletions quandary.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ class Quandary:
-------------------
_ninit : int # number of initial conditions that are propagated
_lindblad_solver : bool # Flag to determine whether lindblad solver vs schroedinger solver
_hamiltonian_filename : str
_hamiltonian_filename_Hsys : str
_hamiltonian_filename_Hc : str
_gatefilename : str
_initstatefilename : str
_initialstate : List[complex] = field(default_factory=list)
Expand Down Expand Up @@ -159,7 +160,8 @@ class Quandary:
# Internal configuration. Should not be changed by user.
_ninit : int = -1
_lindblad_solver : bool = False
_hamiltonian_filename : str = ""
_hamiltonian_filename_Hsys : str = ""
_hamiltonian_filename_Hc : str = ""
_gatefilename : str = ""
_initstatefilename : str = ""
_initialstate : List[complex] = field(default_factory=list)
Expand Down Expand Up @@ -205,6 +207,7 @@ def __post_init__(self):
self.initctrl_MHz = [10.0 for _ in range(len(self.Ne))]
if len(self.Hsys) > 0 and not self.standardmodel: # User-provided Hamiltonian operators
self.standardmodel=False
self.usematfree=False
else: # Using standard Hamiltonian model. Set it up only if needed for computing dT or the carrier wave frequencies later
self.standardmodel=True
if len(self.targetstate) > 0:
Expand Down Expand Up @@ -557,35 +560,28 @@ def __dump(self, *, pcof0=[], runtype="simulation", datadir="./run_dir"):
# If not standard Hamiltonian model, write provided Hamiltonians to a file
if not self.standardmodel:
# Write non-standard Hamiltonians to file
self._hamiltonian_filename= "hamiltonian.dat"
with open(os.path.join(datadir, self._hamiltonian_filename), "w", newline='\n') as f:
# Write system Hamiltonian (complex)
self._hamiltonian_filename_Hsys= "hamiltonian_Hsys.dat"
H = self.Hsys
with open(os.path.join(datadir, self._hamiltonian_filename_Hsys), "w", newline='\n') as f:
f.write("# Hsys_real \n")
Hsyslist = list(np.array(self.Hsys.real).flatten(order='F'))
for value in Hsyslist:
f.write("{:20.13e}\n".format(value))
f.write("# Hsys_imag\n")
Hsyslist = list(np.array(self.Hsys.imag).flatten(order='F'))
for value in Hsyslist:
f.write("{:20.13e}\n".format(value))

# Write control Hamiltonians to file, if given (append to file)
for iosc in range(len(self.Ne)):
# Real part, if given
if len(self.Hc_re)>iosc and len(self.Hc_re[iosc])>0:
with open(os.path.join(datadir, self._hamiltonian_filename), "a", newline='\n') as f:
Hcrelist = list(np.array(self.Hc_re[iosc]).flatten(order='F'))
f.write("# Oscillator {:d} Hc_real \n".format(iosc))
for value in Hcrelist:
f.write("{:20.13e}\n".format(value))
# Imaginary part, if given
if len(self.Hc_im)>iosc and len(self.Hc_im[iosc])>0:
with open(os.path.join(datadir, self._hamiltonian_filename), "a", newline='\n') as f:
Hcimlist = list(np.array(self.Hc_im[iosc]).flatten(order='F'))
f.write("# Oscillator {:d} Hc_imag \n".format(iosc))
for value in Hcimlist:
f.write("{:20.13e}\n".format(value))
nz = np.nonzero(H)
for i, j in zip(*nz):
v = H[i, j]
f.write(f"{i} {j} {v.real:.13e} {v.imag:.13e}\n")
# Write control Hamiltonians, if given
if len(self.Hc_re)>0 or len(self.Hc_im)>0:
self._hamiltonian_filename_Hc = "hamiltonian_Hc.dat"
with open(os.path.join(datadir, self._hamiltonian_filename_Hc), "w", newline='\n') as f:
for iosc, (Hc_re, Hc_im) in enumerate(zip(self.Hc_re, self.Hc_im)):
Hc = np.array(Hc_re) + 1j * np.array(Hc_im)
nz = np.nonzero(Hc)
f.write(f"# Oscillator {iosc} \n")
for i, j in zip(*nz):
v = Hc[i, j]
f.write(f"{iosc} {i} {j} {v.real:.13e} {v.imag:.13e}\n")
if self.verbose:
print("Hamiltonian operators written to ", os.path.join(datadir, self._hamiltonian_filename))
print("Hamiltonian operators written to ", os.path.join(datadir, self._hamiltonian_filename_Hsys), os.path.join(datadir, self._hamiltonian_filename_Hc))

# Initializing the control parameter vector 'pcof0'
# 1. If the initial parameter vector (list) is given with the 'pcof0' argument, the list will be dumped to a file with name self.pcof0_filename := "pcof0.dat".
Expand Down Expand Up @@ -712,7 +708,10 @@ def __dump(self, *, pcof0=[], runtype="simulation", datadir="./run_dir"):
mystring += "linearsolver_type = gmres\n"
mystring += "linearsolver_maxiter = 20\n"
if not self.standardmodel:
mystring += "hamiltonian_file= "+str(self._hamiltonian_filename)+"\n"
if len(self._hamiltonian_filename_Hsys) > 0:
mystring += "hamiltonian_file_Hsys= "+str(self._hamiltonian_filename_Hsys)+"\n"
if len(self._hamiltonian_filename_Hc) > 0:
mystring += "hamiltonian_file_Hc= "+str(self._hamiltonian_filename_Hc)+"\n"
mystring += "timestepper = "+str(self.timestepper)+ "\n"
if self.rand_seed is not None and self.rand_seed >= 0:
mystring += "rand_seed = "+str(int(self.rand_seed))+ "\n"
Expand Down
Loading