void MGPreconditioner :: MgTest () const { cout << "Compute eigenvalues" << endl; const BaseMatrix & amat = GetAMatrix(); const BaseMatrix & pre = GetMatrix(); int eigenretval; EigenSystem eigen (amat, pre); eigen.SetPrecision(1e-30); eigen.SetMaxSteps(1000); eigenretval = eigen.Calc(); eigen.PrintEigenValues (*testout); (cout) << " Min Eigenvalue : " << eigen.EigenValue(mgnumber) << endl; (cout) << " Max Eigenvalue : " << eigen.MaxEigenValue() << endl; (cout) << " Condition " << eigen.MaxEigenValue()/eigen.EigenValue(mgnumber) << endl; (*testout) << " Min Eigenvalue : " << eigen.EigenValue(mgnumber) << endl; (*testout) << " Max Eigenvalue : " << eigen.MaxEigenValue() << endl; (*testout) << " Condition " << eigen.MaxEigenValue()/eigen.EigenValue(mgnumber) << endl; static ofstream condout (mgfile.c_str()); // double cond; condout << bfa->GetFESpace()->GetNDof() << "\t" << bfa->GetFESpace()->GetOrder() << "\t" << eigen.EigenValue(mgnumber) << "\t" << eigen.MaxEigenValue() << "\t" << eigen.MaxEigenValue()/eigen.EigenValue(mgnumber) << "\t" << endl; if(testresult_ok) *testresult_ok = eigenretval; if(testresult_min) *testresult_min = eigen.EigenValue(mgnumber); if(testresult_max) *testresult_max = eigen.MaxEigenValue(); }
virtual void Update () { // delete inverse; if (GetTimeStamp() == bfa->GetTimeStamp()) return; timestamp = bfa->GetTimeStamp(); cout << IM(3) << "Update Direct Solver Preconditioner" << flush; try { auto have_sparse_fact = dynamic_pointer_cast<SparseFactorization> (inverse); if (have_sparse_fact && have_sparse_fact -> SupportsUpdate()) { if (have_sparse_fact->GetAMatrix() == bfa->GetMatrixPtr()) { // cout << "have the same matrix, can update factorization" << endl; have_sparse_fact->Update(); return; } } bfa->GetMatrix().SetInverseType (inversetype); shared_ptr<BitArray> freedofs = bfa->GetFESpace()->GetFreeDofs (bfa->UsesEliminateInternal()); inverse = bfa->GetMatrix().InverseMatrix(freedofs); } catch (exception & e) { throw Exception (string("caught exception in DirectPreconditioner: \n") + e.what() + "\nneeds a sparse matrix (or has memory problems)"); } }
void Preconditioner :: Timing () const { cout << IM(1) << "Timing Preconditioner ... " << flush; const BaseMatrix & amat = GetAMatrix(); const BaseMatrix & pre = GetMatrix(); clock_t starttime; double time; starttime = clock(); BaseVector & vecf = *pre.CreateVector(); BaseVector & vecu = *pre.CreateVector(); vecf = 1; int steps = 0; do { vecu = pre * vecf; steps++; time = double(clock() - starttime) / CLOCKS_PER_SEC; } while (time < 2.0); cout << IM(1) << " 1 step takes " << time / steps << " seconds" << endl; starttime = clock(); steps = 0; do { vecu = amat * vecf; steps++; time = double(clock() - starttime) / CLOCKS_PER_SEC; } while (time < 2.0); cout << IM(1) << ", 1 matrix takes " << time / steps << " seconds" << endl; }
int run_coupled_twiss_output(RUN *run, LINE_LIST *beamline, double *starting_coord) { char JOBVL, JOBVR; int N, LDA, LDVL, LDVR, lwork, info, i, j, k; double A[36], WR[6], WI[6], VL[36], VR[36], work[1000]; double emit[3], Norm[3], Vnorm[36]; double Amatrix[108], SigmaMatrix[6][6]; int matDim, eigenModesNumber; double transferMatrix[36]; VMATRIX *M, *M1; double **R; ELEMENT_LIST *eptr, *eptr0; long nElements, lastNElements, iElement; double betax1, betax2, betay1, betay2, etax, etay, tilt; if (!initialized) return 0; if (verbosity>1) fprintf(stdout, "\n* Computing coupled sigma matrix\n"); if (emittances_from_twiss_command) { if (!(beamline->flags&BEAMLINE_TWISS_DONE)) { fprintf(stderr, "emittances_from_twiss_command was set but twiss calculations not seen"); return(1); } if (!(beamline->flags&BEAMLINE_RADINT_DONE)) { fprintf(stderr, "emittances_from_twiss_command was set but radiation integral calculations not seen"); return(1); } emit_x = beamline->radIntegrals.ex0; sigma_dp = beamline->radIntegrals.sigmadelta; if (verbosity>1) fprintf(stdout, "Raw emittance = %e, momentum spread = %e\n", emit_x, sigma_dp); } fflush(stdout); emit[0] = emit_x; emit[1] = emit_x*emittance_ratio; /* Count the number of elements from the recirc element to the end. */ /* Also store the pointer to the recirc element. */ eptr = eptr0 = &(beamline->elem); nElements = lastNElements = beamline->n_elems; while (eptr) { if (eptr->type==T_RECIRC) { lastNElements = nElements; eptr0 = eptr; } eptr = eptr->succ; nElements--; } nElements = lastNElements; if (starting_coord) { /* use the closed orbit to compute the on-orbit R matrix */ M1 = tmalloc(sizeof(*M1)); initialize_matrices(M1, 1); for (i=0; i<6; i++) { M1->C[i] = starting_coord[i]; M1->R[i][i] = 1; } M = accumulate_matrices(eptr0, run, M1, concat_order, 0); free_matrices(M1); free(M1); M1 = NULL; } else M = accumulate_matrices(eptr0, run, NULL, concat_order, 0); R = M->R; if (verbosity > 2) { long order; order = M->order; M->order = 1; print_matrices(stdout, "One-turn matrix:", M); M->order = order; } /* Determination of matrix dimension for these calculations. */ if (calculate_3d_coupling != 1) { matDim=4; } else { if (abs(R[4][4])+abs(R[5][5])>=2) { printf("Either there is no cavity or 3rd mode is unstable. Only 2 modes will be calculated.\n"); matDim=4; } else { matDim=6; } } eigenModesNumber=matDim/2; /*--- Reducing matrix dimensions, A is reduced R */ for (i=0; i<matDim; i++) { for (j=0; j<matDim; j++) { A[i*matDim+j]=R[j][i]; } } free_matrices(M); free(M); M = NULL; /*--- Changing time sign for symplecticity... */ if (matDim == 6) { for (i=0; i<6; i++) { A[24+i]=-1.0*A[24+i]; A[i*6+4]=-1.0*A[i*6+4]; } } if (verbosity > 3) { MatrixPrintout((double*)&A, &matDim, &matDim, 1); } /*--- Calculating eigenvectors using dgeev_ ... */ JOBVL='N'; JOBVR='V'; N=matDim; LDA=matDim; LDVL=1; LDVR=matDim; lwork=204; #if defined(SUNPERF) || defined(LAPACK) || defined(CLAPACK) dgeev_((char*)&JOBVL, (char*)&JOBVR, (int*)&N, (double*)&A, (int*)&LDA, (double*)&WR, (double*)&WI, (double*)&VL, (int*)&LDVL, (double*)&VR, (int*)&LDVR, (double*)&work, (int*)&lwork, (int*)&info); #else fprintf(stderr, "Error calling dgeev. You will need to install LAPACK and rebuild elegant\n"); return(1); #endif if (info != 0) { if (info < 0) { printf("Error calling dgeev, argument %d.\n", abs(info)); } if (info > 0) { printf("Error running dgeev, calculation of eigenvalue number %d failed.\n", info); } return(1); } if (verbosity > 0) { printf("Info: %d ; %f \n", info, work[0]); for(i=0; i<matDim; i++) { printf("%d: %9.6f + i* %10.6f\n",i,WR[i],WI[i]); } fflush(stdout); } if (verbosity > 1) { printf("Non-normalized vectors:\n"); MatrixPrintout((double*)&VR, &matDim, &matDim, 1); fflush(stdout); } /*--- Sorting of eigenvalues and eigenvectors according to (x,y,z)... */ SortEigenvalues((double*)&WR, (double*)&WI, (double*)&VR, matDim, eigenModesNumber, verbosity); /*--- Normalization of eigenvectors... */ for (k=0; k<eigenModesNumber; k++) { Norm[k]=0; for (i=0; i<eigenModesNumber; i++) { /* Index = Irow*matDim + Icolumn */ Norm[k]+=VR[2*k*matDim+2*i+1]*VR[(2*k+1)*matDim+2*i]-VR[2*k*matDim+2*i]*VR[(2*k+1)*matDim+2*i+1]; } Norm[k]=1.0/sqrt(fabs(Norm[k])); if (verbosity > 2) { printf("Norm[%d]= %12.4e \n",k,Norm[k]); } } for (k=0; k<eigenModesNumber; k++) { for (i=0; i<matDim; i++) { Vnorm[k*2*matDim+i]=VR[k*2*matDim+i]*Norm[k]; Vnorm[(k*2+1)*matDim+i]=VR[(k*2+1)*matDim+i]*Norm[k]; } } if (verbosity > 1) { printf("Normalized vectors:\n"); MatrixPrintout((double*)&Vnorm, &matDim, &matDim, 1); } if (SDDScoupledInitialized) { /*--- Prepare the output file */ if (!SDDS_StartPage(&SDDScoupled, nElements)) { fflush(stdout); SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } /*--- Loop over elements */ iElement=0; eptr = eptr0; while (eptr) { if (verbosity > 0) { printf("\nElement number %ld: %s\n", iElement, eptr->name); fflush(stdout); } if (!eptr->accumMatrix) { fprintf(stderr, "Error: no accumulated matrix found for element %s", eptr->name); return(1); } /*--- Reducing matrix dimensions */ R = eptr->accumMatrix->R; for (i=0; i<matDim; i++) { for (j=0; j<matDim; j++) { transferMatrix[i*matDim+j]=R[j][i]; } } /*--- Changing time sign for symplecticity... */ if (matDim == 6) { for (i=0; i<6; i++) { transferMatrix[24+i]= -1.0*transferMatrix[24+i]; transferMatrix[i*6+4]=-1.0*transferMatrix[i*6+4]; } } /*--- Calculating A matrices (product of eigenvectors)... */ GetAMatrix((double*)&Vnorm, (double*)&transferMatrix, (double*)&Amatrix, &eigenModesNumber, &matDim); if (verbosity > 1) { for (k=0; k<eigenModesNumber; k++) { printf("A matrix for mode %d\n", k); MatrixPrintout((double*)&Amatrix[k*matDim*matDim], &matDim, &matDim, 1); } } /*--- Calculating sigma matrix... */ if (eigenModesNumber == 3) { emit[2]=sigma_dp*sigma_dp*Amatrix[2*matDim*matDim+4*matDim+4]; } for (i=0; i<matDim; i++) { for (j=0; j<matDim; j++) { SigmaMatrix[i][j]=0; for (k=0; k<eigenModesNumber; k++) { SigmaMatrix[i][j]+=emit[k]*Amatrix[k*matDim*matDim+i*matDim+j]; } } } if (verbosity > 0) { printf("Sigma matrix:\n"); MatrixPrintout((double*)&SigmaMatrix, &matDim, &matDim, 2); } tilt=0.5*atan(2*SigmaMatrix[0][2]/(SigmaMatrix[0][0]-SigmaMatrix[2][2])); if (SDDScoupledInitialized) { /*--- Calculating beam sizes: 0-SigmaX, 1-SigmaXP, 2-SigmaY, 3-SigmaYP, 4-BeamTilt, 5-BunchLength */ if (!SDDS_SetRowValues(&SDDScoupled, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iElement, "ElementName", eptr->name, "s", eptr->end_pos, "Sx", sqrt(SigmaMatrix[0][0]), "Sxp", sqrt(SigmaMatrix[1][1]), "Sy", sqrt(SigmaMatrix[2][2]), "Syp", sqrt(SigmaMatrix[3][3]), "xyTilt", tilt, "Ss", eigenModesNumber==3?sqrt(SigmaMatrix[4][4]):-1, NULL)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } if (verbosity > 0) { printf("SigmaX = %12.4e, SigmaY = %12.4e, Beam tilt = %12.4e \n", sqrt(SigmaMatrix[0][0]), sqrt(SigmaMatrix[2][2]), 0.5*atan(2*SigmaMatrix[0][2]/(SigmaMatrix[0][0]-SigmaMatrix[2][2]))); printf("SigmaXP = %12.4e, SigmaYP = %12.4e, \n", sqrt(SigmaMatrix[1][1]), sqrt(SigmaMatrix[3][3])); if (eigenModesNumber==3) { printf("Bunch length = %12.4e \n", sqrt(SigmaMatrix[4][4])); } } betax1 = Amatrix[0]; betax2 = Amatrix[1*matDim*matDim]; betay1 = Amatrix[2*matDim+2]; betay2 = Amatrix[1*matDim*matDim+2*matDim+2]; etax = sqrt(Amatrix[2*matDim*matDim]*Amatrix[2*matDim*matDim+4*matDim+4]); etay = sqrt(Amatrix[2*matDim*matDim+2*matDim+2]*Amatrix[2*matDim*matDim+4*matDim+4]); if (SDDScoupledInitialized) { if (!SDDS_SetRowValues(&SDDScoupled, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iElement, "betax1", betax1, "betax2", betax2, "betay1", betay1, "betay2", betay2, "etax", etax, "etay", etay, NULL)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } if (output_sigma_matrix) { char name[100]; for (i=0; i<matDim; i++) for (j=i; j<matDim; j++) { sprintf(name, "S%d%d", i+1, j+1); if (!SDDS_SetRowValues(&SDDScoupled, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iElement, name, SigmaMatrix[i][j], NULL)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } } } if (verbosity > 0) { printf("betax_1 = %12.4e, betax_2 = %12.4e \n", Amatrix[0], Amatrix[1*matDim*matDim]); printf("betay_1 = %12.4e, betay_2 = %12.4e \n", Amatrix[2*matDim+2], Amatrix[1*matDim*matDim+2*matDim+2]); printf("etax = %12.4e, etay = %12.4e \n", sqrt(Amatrix[2*matDim*matDim]*Amatrix[2*matDim*matDim+4*matDim+4]), sqrt(Amatrix[2*matDim*matDim+2*matDim+2]*Amatrix[2*matDim*matDim+4*matDim+4])); fflush(stdout); } if (eptr->type==T_MARK && ((MARK*)eptr->p_elem)->fitpoint) store_fitpoint_ctwiss_parameters((MARK*)eptr->p_elem, eptr->name, eptr->occurence, betax1, betax2, betay1, betay2, etax, etay, tilt); iElement++; eptr = eptr->succ; } if (SDDScoupledInitialized && !SDDS_WritePage(&SDDScoupled)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } return(0); }