| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
| 3 | SLEPc - Scalable Library for Eigenvalue Problem Computations | ||
| 4 | Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain | ||
| 5 | |||
| 6 | This file is part of SLEPc. | ||
| 7 | SLEPc is distributed under a 2-clause BSD license (see LICENSE). | ||
| 8 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
| 9 | */ | ||
| 10 | |||
| 11 | static char help[] = "2-D discrete Gross-Pitaevskii model solved as a Nonlinear Eigenvalue Problem with eigenvector dependence (NEPv).\n\n" | ||
| 12 | "Implemented by embedding an EPS inside a nonlinear SNES loop.\n\n" | ||
| 13 | "The Gross-Pitaevskii (GP) equation models the ground state of a rotating Bose-Einstein Condensate (BEC).\n" | ||
| 14 | "The goal is to self-consistently find the macroscopic wavefunction (eigenvector) and its corresponding\n" | ||
| 15 | "chemical potential or ground-state energy (eigenvalue) under a magnetic trap.\n\n" | ||
| 16 | "The nonlinear Hamiltonian matrix is defined as H(x) = A0 + beta * Diag(rho(x)), where:\n" | ||
| 17 | " A0 = base linear Hamiltonian containing 2-D kinetic energy, a harmonic trap potential, and angular momentum rotation.\n" | ||
| 18 | " rho = condensate density vector computed from the ground-state wavefunction x as rho = |x|^2.\n\n" | ||
| 19 | "The command line options are:\n" | ||
| 20 | " -n <n>, where <n> = number of grid points per dimension.\n" | ||
| 21 | " -beta <beta>, where <beta> = real scaling parameter controlling the nonlinearity and strength of the atomic interactions.\n" | ||
| 22 | " -symm <bool>: trap potential profile (true = symmetric, false = asymmetric).\n" | ||
| 23 | " -verbose, to print the converged Hamiltonian diagonal and its sum.\n\n"; | ||
| 24 | |||
| 25 | #include <slepceps.h> | ||
| 26 | |||
| 27 | /* | ||
| 28 | Context structure to store the necessary data regarding the discrete Gross-Pitaevskii (DGP) problem | ||
| 29 | as well as the objects needed for the self-consistent field (SCF) iteration. | ||
| 30 | */ | ||
| 31 | typedef struct { | ||
| 32 | // DGP context | ||
| 33 | |||
| 34 | // Inputs | ||
| 35 | PetscInt N; // Number of points per dimension | ||
| 36 | PetscReal beta; // Parameter controlling the nonlinearity | ||
| 37 | PetscBool symm; // True: Symmetric potential, False: Asymmetric potential | ||
| 38 | |||
| 39 | // Constants | ||
| 40 | PetscReal L; // Length of the semi-domain [-L, L] | ||
| 41 | PetscReal h; // Step size | ||
| 42 | PetscReal omega; // Angular frequency | ||
| 43 | |||
| 44 | // Working vectors and matrices | ||
| 45 | Vec rho; // Vector to store the condensate density | ||
| 46 | Vec z; // Intermediate vector to store the result z = beta * rho | ||
| 47 | Mat A0; // Base linear Hamiltonian | ||
| 48 | |||
| 49 | // SCF context | ||
| 50 | EPS eps; // Solver for each H | ||
| 51 | Mat H; // Hamiltonian | ||
| 52 | Vec x; // Eigenvector | ||
| 53 | } DGPContext; | ||
| 54 | |||
| 55 | /* | ||
| 56 | Initialize the context for the 2D discrete Gross-Pitaevskii problem. | ||
| 57 | |||
| 58 | This function allocates the necessary memory and builds the base linear | ||
| 59 | Hamiltonian A0 as | ||
| 60 | |||
| 61 | A0 = h^2 * ( -0.5*L + V - omega*1i*L_z ) | ||
| 62 | |||
| 63 | where | ||
| 64 | L is the discrete 2-D Laplacian, | ||
| 65 | L_z is the discrete 2-D angular momentum operator (without scaling), and | ||
| 66 | V is a diagonal matrix with the potential for each coordinate (x,y): | ||
| 67 | (x.^2+y.^2)/2 for the symmetric case, (x.^2+100*y.^2)/2 for the non-symmetric case. | ||
| 68 | |||
| 69 | Arguments: | ||
| 70 | N - Grid size per dimension | ||
| 71 | beta - Parameter controlling the repulsive interaction of the condensate | ||
| 72 | symm - Defines the shape of the magnetic trap (True = symmetric, False = asymmetric) | ||
| 73 | ctx_out - Pointer to the memory address where the created context will be stored | ||
| 74 | */ | ||
| 75 | 20 | PetscErrorCode DGPCreate(MPI_Comm comm,PetscInt N,PetscReal beta,PetscBool symm,DGPContext **ctx_out) | |
| 76 | { | ||
| 77 | 20 | DGPContext *ctx; | |
| 78 | |||
| 79 | 20 | PetscInt Istart,Iend,i,II,j; | |
| 80 | 20 | PetscReal h2; | |
| 81 | 20 | PetscReal x,y,V; | |
| 82 | 20 | PetscScalar alpha; | |
| 83 | |||
| 84 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
20 | PetscFunctionBeginUser; |
| 85 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscNew(&ctx)); |
| 86 | |||
| 87 | // Inputs | ||
| 88 | 20 | ctx->N=N; | |
| 89 | 20 | ctx->beta=beta; | |
| 90 | 20 | ctx->symm=symm; | |
| 91 | |||
| 92 | // Constants | ||
| 93 | 20 | ctx->L=1.0; | |
| 94 | 20 | ctx->h=2.0*ctx->L/(ctx->N+1.0); | |
| 95 | 20 | ctx->omega=0.85; | |
| 96 | 20 | h2=ctx->h*ctx->h; | |
| 97 | |||
| 98 | // 1. Create A0 | ||
| 99 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatCreate(comm,&ctx->A0)); |
| 100 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatSetSizes(ctx->A0,PETSC_DECIDE,PETSC_DECIDE,N*N,N*N)); |
| 101 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatSetFromOptions(ctx->A0)); |
| 102 | |||
| 103 | // 2. Fill A0 | ||
| 104 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatGetOwnershipRange(ctx->A0,&Istart,&Iend)); |
| 105 | |||
| 106 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
|
200 | for (II=Istart;II<Iend;II++) { |
| 107 | 180 | i=II/ctx->N; j=II-i*ctx->N; | |
| 108 | |||
| 109 | // Potential for mesh point with coordinates (x,y) | ||
| 110 | 180 | x=-ctx->L+(j+1)*ctx->h; | |
| 111 | 180 | y=-ctx->L+(i+1)*ctx->h; | |
| 112 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
180 | if (ctx->symm) V=0.5*(x*x+y*y); |
| 113 | ✗ | else V=0.5*(x*x+100.0*y*y); | |
| 114 | |||
| 115 | 180 | alpha = -h2*ctx->omega/(2.0*ctx->h)*PETSC_i; | |
| 116 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
180 | PetscCall(MatSetValue(ctx->A0,II,II,0.5*4.0+h2*V,INSERT_VALUES)); |
| 117 |
6/8✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
180 | if (i>0) PetscCall(MatSetValue(ctx->A0,II,II-ctx->N,-0.5+alpha*x,INSERT_VALUES)); |
| 118 |
6/8✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
180 | if (i<ctx->N-1) PetscCall(MatSetValue(ctx->A0,II,II+ctx->N,-0.5-alpha*x,INSERT_VALUES)); |
| 119 |
6/8✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
180 | if (j>0) PetscCall(MatSetValue(ctx->A0,II,II-1,-0.5-alpha*y,INSERT_VALUES)); |
| 120 |
6/8✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
180 | if (j<ctx->N-1) PetscCall(MatSetValue(ctx->A0,II,II+1,-0.5+alpha*y,INSERT_VALUES)); |
| 121 | } | ||
| 122 | |||
| 123 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatAssemblyBegin(ctx->A0,MAT_FINAL_ASSEMBLY)); |
| 124 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatAssemblyEnd(ctx->A0,MAT_FINAL_ASSEMBLY)); |
| 125 | |||
| 126 | // 3. Create vectors to store the condensate density | ||
| 127 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatCreateVecs(ctx->A0,&ctx->rho,&ctx->z)); |
| 128 | |||
| 129 | 20 | *ctx_out=ctx; | |
| 130 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
20 | PetscFunctionReturn(PETSC_SUCCESS); |
| 131 | } | ||
| 132 | |||
| 133 | /* | ||
| 134 | Configure the SLEPc objects necessary for the SCF iteration. | ||
| 135 | |||
| 136 | This function prepares the Hamiltonian matrix by cloning the structure of A0, | ||
| 137 | initializes the vector to store the condensate state, and configures the eigenvalue | ||
| 138 | solver (EPS) by defining the problem type and adjusting its tolerance. | ||
| 139 | |||
| 140 | Arguments: | ||
| 141 | ctx - Pointer to the previously initialized DGP context | ||
| 142 | tol - Desired tolerance for the internal eigenvalue solver | ||
| 143 | */ | ||
| 144 | 20 | PetscErrorCode DGPSetupSCF(DGPContext *ctx,PetscReal tol) | |
| 145 | { | ||
| 146 | 20 | MPI_Comm comm; | |
| 147 | |||
| 148 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
20 | PetscFunctionBeginUser; |
| 149 | 20 | comm = PetscObjectComm((PetscObject)ctx->A0); | |
| 150 | /* Prepare the H matrix */ | ||
| 151 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatDuplicate(ctx->A0,MAT_DO_NOT_COPY_VALUES,&ctx->H)); |
| 152 | |||
| 153 | /* Configure the eigenvector x */ | ||
| 154 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatCreateVecs(ctx->A0,&ctx->x,NULL)); |
| 155 | |||
| 156 | /* Configure SLEPc EPS */ | ||
| 157 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSCreate(comm,&ctx->eps)); |
| 158 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSetProblemType(ctx->eps,EPS_HEP)); |
| 159 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSetWhichEigenpairs(ctx->eps,EPS_SMALLEST_REAL)); |
| 160 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSetDimensions(ctx->eps,1,PETSC_DECIDE,PETSC_DECIDE)); |
| 161 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSetTolerances(ctx->eps,tol,PETSC_DECIDE)); |
| 162 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSetFromOptions(ctx->eps)); |
| 163 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
4 | PetscFunctionReturn(PETSC_SUCCESS); |
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | Generate the initial guess X0 by solving the base linear Hamiltonian. | ||
| 168 | |||
| 169 | This function solves the eigenvalue problem (A0 * x = E * x) and fills | ||
| 170 | the vector x with the lowest energy eigenvector obtained. This | ||
| 171 | initial guess improves the convergence of the SCF loop. | ||
| 172 | |||
| 173 | Arguments: | ||
| 174 | ctx - Pointer to the previously initialized DGP context | ||
| 175 | */ | ||
| 176 | 20 | PetscErrorCode DGPGenerateInitialGuess(DGPContext *ctx) | |
| 177 | { | ||
| 178 | 20 | PetscInt nconv; | |
| 179 | 20 | MPI_Comm comm; | |
| 180 | |||
| 181 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
20 | PetscFunctionBeginUser; |
| 182 | 20 | comm = PetscObjectComm((PetscObject)ctx->A0); | |
| 183 | /* 1. Configure and solve the base linear problem A0 */ | ||
| 184 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSetOperators(ctx->eps,ctx->A0,NULL)); |
| 185 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSSolve(ctx->eps)); |
| 186 | |||
| 187 | /* Safety check: guarantee that SLEPc found the solution */ | ||
| 188 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSGetConverged(ctx->eps,&nconv)); |
| 189 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
20 | PetscCheck(nconv>=1,comm,PETSC_ERR_NOT_CONVERGED,"SLEPc could not find the initial linear ground state."); |
| 190 | |||
| 191 | /* 2. Extract the eigenvector and store it in x */ | ||
| 192 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSGetEigenvector(ctx->eps,0,ctx->x,NULL)); |
| 193 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
4 | PetscFunctionReturn(PETSC_SUCCESS); |
| 194 | } | ||
| 195 | |||
| 196 | /* | ||
| 197 | Compute the condensate density from the ground-state eigenvector. | ||
| 198 | |||
| 199 | This function computes the density rho(x) as the squared magnitude | ||
| 200 | of the components of the eigenvector X0. The formula used is: rho(x) = |x|.^2. | ||
| 201 | |||
| 202 | Arguments: | ||
| 203 | ctx - Pointer to the initialized DGP context | ||
| 204 | rho_out - Pre-created vector where the computed density will be stored | ||
| 205 | */ | ||
| 206 | 410 | PetscErrorCode DGPCalculateDensity(DGPContext *ctx,Vec rho_out) | |
| 207 | { | ||
| 208 | 410 | PetscInt i,n_loc; | |
| 209 | 410 | const PetscScalar *x_local; | |
| 210 | 410 | PetscScalar *rho_local; | |
| 211 | |||
| 212 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
410 | PetscFunctionBeginUser; |
| 213 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
410 | PetscCall(VecSet(rho_out,0.0)); |
| 214 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
410 | PetscCall(VecGetLocalSize(rho_out,&n_loc)); |
| 215 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
410 | PetscCall(VecGetArray(rho_out,&rho_local)); |
| 216 | |||
| 217 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
410 | PetscCall(VecGetArrayRead(ctx->x,&x_local)); |
| 218 | |||
| 219 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
|
4100 | for (i=0;i<n_loc;i++) { |
| 220 | /* Compute the squared magnitude: rho = Real^2 + Imag^2 */ | ||
| 221 | 3690 | PetscReal mod=PetscAbsScalar(x_local[i]); | |
| 222 | 3690 | rho_local[i]=mod*mod; | |
| 223 | } | ||
| 224 | |||
| 225 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
410 | PetscCall(VecRestoreArrayRead(ctx->x,&x_local)); |
| 226 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
410 | PetscCall(VecRestoreArray(rho_out,&rho_local)); |
| 227 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
82 | PetscFunctionReturn(PETSC_SUCCESS); |
| 228 | } | ||
| 229 | |||
| 230 | /* | ||
| 231 | Build the Hamiltonian from an input density. | ||
| 232 | |||
| 233 | This function assembles the updated Hamiltonian matrix stored in the context | ||
| 234 | using the formula: H = A0 + beta * Diag(rho_in). | ||
| 235 | |||
| 236 | Arguments: | ||
| 237 | ctx - Pointer to the initialized DGP context (ctx->H is updated) | ||
| 238 | rho_in - Vector with the input density | ||
| 239 | */ | ||
| 240 | 390 | PetscErrorCode DGPBuildHamiltonian(DGPContext *ctx,Vec rho_in) | |
| 241 | { | ||
| 242 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
390 | PetscFunctionBeginUser; |
| 243 | // 1. Build H = A0 + beta * Diag(rho_in) | ||
| 244 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(MatCopy(ctx->A0,ctx->H,SAME_NONZERO_PATTERN)); |
| 245 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(VecCopy(rho_in,ctx->z)); |
| 246 | |||
| 247 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(VecScale(ctx->z,ctx->beta)); |
| 248 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(MatDiagonalSet(ctx->H,ctx->z,ADD_VALUES)); |
| 249 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
78 | PetscFunctionReturn(PETSC_SUCCESS); |
| 250 | } | ||
| 251 | |||
| 252 | /* | ||
| 253 | Evaluation function (Callback) for the SNES nonlinear solver in DGP. | ||
| 254 | |||
| 255 | In each SNES iteration, this function receives a proposed density (rho_in), | ||
| 256 | builds the Hamiltonian, solves the eigenvalue equation, computes the | ||
| 257 | resulting density, and returns the residual F = rho_out - rho_in. | ||
| 258 | |||
| 259 | Arguments: | ||
| 260 | snes - The nonlinear solver context | ||
| 261 | rho_in - Condensate density proposed by SNES | ||
| 262 | F - Vector where the computed residual will be stored | ||
| 263 | ctx_void - Pointer to the user's DGP context (DGPContext) | ||
| 264 | */ | ||
| 265 | 390 | PetscErrorCode DGPIterationSCF(SNES snes,Vec rho_in,Vec F,void *ctx_void) | |
| 266 | { | ||
| 267 | 390 | DGPContext *ctx=(DGPContext*)ctx_void; | |
| 268 | 390 | PetscInt nconv; | |
| 269 | 390 | MPI_Comm comm; | |
| 270 | |||
| 271 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
390 | PetscFunctionBeginUser; |
| 272 | 390 | comm = PetscObjectComm((PetscObject)ctx->A0); | |
| 273 | /* 1. Build the physics (Hamiltonian) with the guess proposed by SNES */ | ||
| 274 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(DGPBuildHamiltonian(ctx,rho_in)); |
| 275 | |||
| 276 | /* 2. Solve the eigenvalue problem with the current H */ | ||
| 277 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(EPSSetOperators(ctx->eps,ctx->H,NULL)); |
| 278 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(EPSSolve(ctx->eps)); |
| 279 | |||
| 280 | // Safety check: verify that SLEPc found the ground state | ||
| 281 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(EPSGetConverged(ctx->eps,&nconv)); |
| 282 |
1/8✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
390 | if (nconv<1) PetscCall(PetscPrintf(comm,"Warning: SLEPc did not find the ground state in this iteration.\n")); |
| 283 | |||
| 284 | /* 3. Extract the new eigenvector and store it directly in ctx->x */ | ||
| 285 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(EPSGetEigenvector(ctx->eps,0,ctx->x,NULL)); |
| 286 | |||
| 287 | /* 4. Compute the new density (rho_out) generated by this eigenvector */ | ||
| 288 | // Store the result in ctx->rho | ||
| 289 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(DGPCalculateDensity(ctx,ctx->rho)); |
| 290 | |||
| 291 | /* 5. Calculate the nonlinear residual: F = rho_out - rho_in */ | ||
| 292 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
390 | PetscCall(VecWAXPY(F,-1.0,ctx->rho,rho_in)); |
| 293 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
78 | PetscFunctionReturn(PETSC_SUCCESS); |
| 294 | } | ||
| 295 | |||
| 296 | /* | ||
| 297 | Free the memory associated with the DGP context. | ||
| 298 | |||
| 299 | This function destroys all internal PETSc objects created during | ||
| 300 | initialization and frees the memory of the main structure. | ||
| 301 | |||
| 302 | Arguments: | ||
| 303 | ctx - Pointer to the DGP context (set to NULL upon completion) | ||
| 304 | */ | ||
| 305 | 20 | PetscErrorCode DGPDestroy(DGPContext **ctx) | |
| 306 | { | ||
| 307 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
20 | PetscFunctionBeginUser; |
| 308 |
2/14✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
20 | if (!*ctx) PetscFunctionReturn(PETSC_SUCCESS); |
| 309 | |||
| 310 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatDestroy(&(*ctx)->A0)); |
| 311 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDestroy(&(*ctx)->rho)); |
| 312 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDestroy(&(*ctx)->z)); |
| 313 | |||
| 314 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(MatDestroy(&(*ctx)->H)); |
| 315 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDestroy(&(*ctx)->x)); |
| 316 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSDestroy(&(*ctx)->eps)); |
| 317 | |||
| 318 |
5/8✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
20 | PetscCall(PetscFree(*ctx)); |
| 319 |
5/12✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
4 | PetscFunctionReturn(PETSC_SUCCESS); |
| 320 | } | ||
| 321 | |||
| 322 | 20 | int main(int argc,char **argv) | |
| 323 | { | ||
| 324 | 20 | DGPContext *ctx; | |
| 325 | 20 | Vec H_diag,rho_guess; | |
| 326 | 20 | PetscScalar diagonal_sum,kr; | |
| 327 | 20 | PetscInt n=3,maxit=100,its; | |
| 328 | 20 | PetscInt nconv; | |
| 329 | 20 | PetscReal beta=2.0,rtol=SLEPC_DEFAULT_TOL,stol=1e-12; | |
| 330 | 20 | SNES snes; | |
| 331 | 20 | Vec F; // Vector to store the residual (F = rho_out - rho_in) | |
| 332 | 20 | PetscBool symm=PETSC_TRUE,verbose=PETSC_FALSE; | |
| 333 | 20 | SNESConvergedReason reason; | |
| 334 | 20 | SNESLineSearch linesearch; | |
| 335 | |||
| 336 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
20 | PetscFunctionBeginUser; |
| 337 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SlepcInitialize(&argc,&argv,NULL,help)); |
| 338 | |||
| 339 | 20 | PetscCheck(PetscDefined(USE_COMPLEX),PETSC_COMM_WORLD,PETSC_ERR_SUP,"This example requires complex scalars"); | |
| 340 | |||
| 341 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"--- DGP SNES SCF ---\n")); |
| 342 | |||
| 343 | /* 1. Read DGP-specific command line options */ | ||
| 344 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL)); |
| 345 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscOptionsGetReal(NULL,NULL,"-beta",&beta,NULL)); |
| 346 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscOptionsGetBool(NULL,NULL,"-symm",&symm,NULL)); |
| 347 | |||
| 348 | /* 2. Initialization of the DGP context and base linear Hamiltonian A0 */ | ||
| 349 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(DGPCreate(PETSC_COMM_WORLD,n,beta,symm,&ctx)); |
| 350 | |||
| 351 | /* 3. Configure objects for the SCF (H matrix, EPS, Vec x) */ | ||
| 352 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(DGPSetupSCF(ctx,rtol*0.1)); |
| 353 | |||
| 354 | /* 4. Generate the initial guess by solving the linear problem A0 */ | ||
| 355 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(DGPGenerateInitialGuess(ctx)); |
| 356 | |||
| 357 | /* 5. Prepare the initial density (rho_guess) from the linear ground state */ | ||
| 358 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDuplicate(ctx->rho,&rho_guess)); |
| 359 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(DGPCalculateDensity(ctx,rho_guess)); |
| 360 | |||
| 361 | /* 6. Prepare the residual vector F by cloning rho */ | ||
| 362 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDuplicate(ctx->rho,&F)); |
| 363 | |||
| 364 | /* 7. Configure the nonlinear solver engine (SNES) with the DGP callback */ | ||
| 365 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESCreate(PETSC_COMM_WORLD,&snes)); |
| 366 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESSetFunction(snes,F,DGPIterationSCF,ctx)); |
| 367 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESSetTolerances(snes,PETSC_DETERMINE,rtol,stol,maxit,PETSC_DETERMINE)); |
| 368 | |||
| 369 | // Default -> NRICHARDSON with step lambda = 1.0 to simulate basic SCF | ||
| 370 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESSetType(snes,SNESNRICHARDSON)); |
| 371 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESGetLineSearch(snes,&linesearch)); |
| 372 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESLineSearchSetType(linesearch,SNESLINESEARCHNONE)); |
| 373 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESLineSearchSetDamping(linesearch,1.0)); |
| 374 | |||
| 375 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESSetFromOptions(snes)); |
| 376 | |||
| 377 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESGetTolerances(snes,NULL,&rtol,NULL,&maxit,NULL)); |
| 378 |
6/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
20 | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Current parameters: n=%" PetscInt_FMT ", beta=%g, symm=%s, rtol=%g, maxit=%" PetscInt_FMT "\n",n,(double)beta,symm ? "True" : "False",(double)rtol,maxit)); |
| 379 | |||
| 380 | /* 8. SCF loop */ | ||
| 381 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nStarting SCF iterations...\n")); |
| 382 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESSolve(snes,NULL,rho_guess)); |
| 383 | |||
| 384 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESGetConvergedReason(snes,&reason)); |
| 385 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESGetIterationNumber(snes,&its)); |
| 386 | |||
| 387 | /* 9. Analysis of results */ | ||
| 388 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
20 | if (reason>0) { |
| 389 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"--> CONVERGENCE REACHED in %" PetscInt_FMT " iterations (Reason: %s).\n",its,SNESConvergedReasons[reason])); |
| 390 | |||
| 391 | /* Extract the eigenvalue of the converged ground state */ | ||
| 392 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSGetConverged(ctx->eps,&nconv)); |
| 393 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
20 | if (nconv>0) { |
| 394 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(EPSGetEigenvalue(ctx->eps,0,&kr,NULL)); |
| 395 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nEigenvalue found = %10.6f\n",(double)PetscRealPart(kr))); |
| 396 | } | ||
| 397 | |||
| 398 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(PetscOptionsHasName(NULL,NULL,"-verbose",&verbose)); |
| 399 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
20 | if (verbose) { |
| 400 | ✗ | PetscCall(MatCreateVecs(ctx->H,NULL,&H_diag)); | |
| 401 | ✗ | PetscCall(MatGetDiagonal(ctx->H,H_diag)); | |
| 402 | ✗ | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Diagonal of the final Hamiltonian:\n")); | |
| 403 | ✗ | PetscCall(VecView(H_diag,PETSC_VIEWER_STDOUT_WORLD)); | |
| 404 | |||
| 405 | ✗ | PetscCall(VecSum(H_diag,&diagonal_sum)); | |
| 406 | ✗ | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Sum of the diagonal (Approx total energy): %g\n",(double)PetscRealPart(diagonal_sum))); | |
| 407 | ✗ | PetscCall(VecDestroy(&H_diag)); | |
| 408 | } | ||
| 409 | |||
| 410 | } else { | ||
| 411 | ✗ | PetscCall(SNESGetConvergedReason(snes,&reason)); | |
| 412 | ✗ | PetscCall(PetscPrintf(PETSC_COMM_WORLD,"--> ERROR: The SCF did not converge (Reason: %s)\n",SNESConvergedReasons[reason])); | |
| 413 | } | ||
| 414 | |||
| 415 | /* 10. Clean up memory */ | ||
| 416 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDestroy(&F)); |
| 417 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(VecDestroy(&rho_guess)); |
| 418 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(SNESDestroy(&snes)); |
| 419 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
20 | PetscCall(DGPDestroy(&ctx)); |
| 420 | |||
| 421 |
2/6✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
20 | PetscCall(SlepcFinalize()); |
| 422 | return 0; | ||
| 423 | } | ||
| 424 | |||
| 425 | /*TEST | ||
| 426 | |||
| 427 | build: | ||
| 428 | requires: complex | ||
| 429 | |||
| 430 | testset: | ||
| 431 | filter: sed -e "s/rtol=1e-05/rtol=1e-08/" -e "s/rtol=1e-16/rtol=1e-08/" -e "s/[0-9]\{1,\} iterations/23 iterations/" -e "s/CONVERGED_SNORM_RELATIVE/CONVERGED_FNORM_RELATIVE/" | ||
| 432 | output_file: output/ex60_1.out | ||
| 433 | test: | ||
| 434 | suffix: 1 | ||
| 435 | test: | ||
| 436 | suffix: 2 | ||
| 437 | args: -snes_type anderson -snes_anderson_m 7 | ||
| 438 | test: | ||
| 439 | suffix: 3 | ||
| 440 | args: -snes_type ngmres -npc_snes_type nrichardson -snes_npc_side right | ||
| 441 | test: | ||
| 442 | suffix: 4 | ||
| 443 | args: -snes_type composite -snes_composite_type additiveoptimal -snes_composite_sneses anderson,nrichardson -sub_0_snes_anderson_m 7 -sub_0_snes_anderson_beta 0.4 | ||
| 444 | |||
| 445 | TEST*/ | ||
| 446 |