88 py::array_t<std::complex<double>, py::array::c_style | py::array::forcecast> initial_psi,
90 std::shared_ptr<Potential> potential,
91 std::shared_ptr<BoundaryCondition> boundary_condition,
94 : grid_(grid), potential_(potential), boundary_condition_(boundary_condition), dt_(dt), mass_(mass)
97 py::buffer_info psi_info = initial_psi.request();
98 if (psi_info.ndim != 2 || psi_info.shape[1] != 4) {
99 throw std::runtime_error(
"El psi inicial debe ser un array de NumPy de forma (N, 4)");
102 throw std::runtime_error(
"El número de puntos en psi debe coincidir con el total de puntos de la malla.");
107 psi_curr_.resize(n_points);
108 psi_prev_.resize(n_points);
109 psi_next_.resize(n_points);
113 for (
size_t i = 0; i < n_points; ++i)
114 for (
size_t j = 0; j < 4; ++j)
115 psi_curr_[i].components[j] = ptr[i * 4 + j];
118 psi_prev_ = psi_curr_;
137 bool is_periodic = (boundary_condition_->get_name() ==
"PeriodicBoundary");
139 for (
size_t i = 0; i < n_points; ++i) {
144 size_t i_prev = (is_periodic && i == 0) ? n_points - 1 : i - 1;
145 size_t i_next = (is_periodic && i == n_points - 1) ? 0 : i + 1;
147 h_spatial_psi = (
Dirac::complex(0, -1.0) / (2.0 * spacing[0])) * h_spatial_psi;
149 else if (grid_.
get_dim() == 2) {
150 size_t nx = shape[0];
151 size_t ny = shape[1];
154 size_t ix_prev = (is_periodic && ix == 0) ? nx - 1 : ix - 1;
155 size_t ix_next = (is_periodic && ix == nx - 1) ? 0 : ix + 1;
156 size_t iy_prev = (is_periodic && iy == 0) ? ny - 1 : iy - 1;
157 size_t iy_next = (is_periodic && iy == ny - 1) ? 0 : iy + 1;
161 h_spatial_psi = (
Dirac::complex(0, -1.0) / (2.0 * spacing[0])) * dx_psi +
164 else if (grid_.
get_dim() == 3) {
165 size_t nx = shape[0];
166 size_t ny = shape[1];
167 size_t nz = shape[2];
169 size_t iy = (i / nx) % ny;
170 size_t iz = i / (nx * ny);
172 size_t ix_prev = (is_periodic && ix == 0) ? nx - 1 : ix - 1;
173 size_t ix_next = (is_periodic && ix == nx - 1) ? 0 : ix + 1;
174 size_t iy_prev = (is_periodic && iy == 0) ? ny - 1 : iy - 1;
175 size_t iy_next = (is_periodic && iy == ny - 1) ? 0 : iy + 1;
176 size_t iz_prev = (is_periodic && iz == 0) ? nz - 1 : iz - 1;
177 size_t iz_next = (is_periodic && iz == nz - 1) ? 0 : iz + 1;
182 h_spatial_psi = (
Dirac::complex(0, -1.0) / (2.0 * spacing[0])) * dx_psi +
188 std::vector<double> coords = grid_.
get_coords(i);
189 double v_at_i = potential_->evaluate(coords);
194 psi_next_[i] = psi_prev_[i] - (
Dirac::complex(0, 2.0) * dt_) * h_psi;
198 boundary_condition_->apply(psi_next_, grid_);
201 psi_prev_ = psi_curr_;
202 psi_curr_ = psi_next_;