void computeChromCorrectionMatrix(RUN *run, LINE_LIST *beamline, CHROM_CORRECTION *chrom) { VMATRIX *M; double chromx, chromy; double chromx0, chromy0; double K2=0.0, *K2ptr; ELEMENT_LIST *context; long i, count, K2_param=0; MATRIX *C, *Ct, *CtC, *inv_CtC; m_alloc(&C, 2, chrom->n_families); m_alloc(&Ct, chrom->n_families, 2); m_alloc(&CtC, chrom->n_families, chrom->n_families); m_alloc(&inv_CtC, chrom->n_families, chrom->n_families); if (chrom->T) m_free(&(chrom->T)); if (chrom->dK2) m_free(&(chrom->dK2)); if (chrom->dchrom) m_free(&(chrom->dchrom)); m_alloc(&(chrom->T), chrom->n_families, 2); m_alloc(&(chrom->dK2), chrom->n_families, 1); m_alloc(&(chrom->dchrom), 2, 1); if (verbosityLevel>2) { fprintf(stdout, "Computing chromaticity influence matrix for all named sextupoles.\n"); fflush(stdout); } computeChromaticities(&chromx0, &chromy0, NULL, NULL, NULL, NULL, beamline->twiss0, beamline->elast->twiss, M=beamline->matrix); M = NULL; for (i=0; i<chrom->n_families; i++) { count = 0; context = NULL; while ((context=find_element(chrom->name[i], &context, beamline->elem_twiss))) { if (!count && !(K2_param=confirm_parameter("K2", context->type))) { fprintf(stdout, "error: element %s does not have K2 parameter\n", context->name); fflush(stdout); exitElegant(1); } if (!(K2ptr = (double*)(context->p_elem + entity_description[context->type].parameter[K2_param].offset))) bombElegant("K2ptr NULL in setup_chromaticity_correction", NULL); if (count==0) K2 = *K2ptr; *K2ptr = K2 + chrom->sextupole_tweek; if (context->matrix) { free_matrices(context->matrix); free(context->matrix); context->matrix = NULL; } compute_matrix(context, run, NULL); count++; } if (count==0) { fprintf(stdout, "error: element %s is not in the beamline.\n", chrom->name[i]); fflush(stdout); exitElegant(1); } if (beamline->links) { /* rebaseline_element_links(beamline->links, run, beamline); */ assert_element_links(beamline->links, run, beamline, STATIC_LINK+DYNAMIC_LINK); } if (M) { free_matrices(M); free(M); M = NULL; } M = full_matrix(beamline->elem_twiss, run, 2); computeChromaticities(&chromx, &chromy, NULL, NULL, NULL, NULL, beamline->twiss0, beamline->elast->twiss, M); C->a[0][i] = (chromx-chromx0)/chrom->sextupole_tweek; C->a[1][i] = (chromy-chromy0)/chrom->sextupole_tweek; if (C->a[0][i]==0 || C->a[1][i]==0) { fprintf(stdout, "error: element %s does not change the chromaticity!\n", chrom->name[i]); fflush(stdout); exitElegant(1); } count = 0; context = NULL; while ((context=find_element(chrom->name[i], &context, beamline->elem_twiss))) { if (!count && !(K2_param=confirm_parameter("K2", context->type))) { fprintf(stdout, "error: element %s does not have K2 parameter\n", context->name); fflush(stdout); exitElegant(1); } if (!(K2ptr = (double*)(context->p_elem + entity_description[context->type].parameter[K2_param].offset))) bombElegant("K2ptr NULL in setup_chromaticity_correction", NULL); if (!K2ptr) bombElegant("K2ptr NULL in setup_chromaticity_correction", NULL); *K2ptr = K2; if (context->matrix) { free_matrices(context->matrix); free(context->matrix); context->matrix = NULL; } compute_matrix(context, run, NULL); count++; } } if (M) { free_matrices(M); free(M); M = NULL; } if (beamline->matrix) { free_matrices(beamline->matrix); free(beamline->matrix); beamline->matrix = NULL; } beamline->matrix = full_matrix(beamline->elem_twiss, run, run->default_order); if (verbosityLevel>1) { fprintf(stdout, "\nfamily dCHROMx/dK2 dCHROMy/dK2\n"); fflush(stdout); for (i=0; i<chrom->n_families; i++) fprintf(stdout, "%10s: %14.7e %14.7e\n", chrom->name[i], C->a[0][i], C->a[1][i]); fflush(stdout); } m_trans(Ct, C); m_mult(CtC, Ct, C); m_invert(inv_CtC, CtC); m_mult(chrom->T, inv_CtC, Ct); if (verbosityLevel>1) { fprintf(stdout, "\nfamily dK2/dCHROMx dK2/dCHROMy\n"); fflush(stdout); for (i=0; i<chrom->n_families; i++) fprintf(stdout, "%10s: %14.7e %14.7e\n", chrom->name[i], chrom->T->a[i][0], chrom->T->a[i][1]); fflush(stdout); fprintf(stdout, "\n"); fflush(stdout); } m_free(&C); m_free(&Ct); m_free(&CtC); m_free(&inv_CtC); }
long do_chromaticity_correction(CHROM_CORRECTION *chrom, RUN *run, LINE_LIST *beamline, double *clorb, long step, long last_iteration) { VMATRIX *M; double chromx0, chromy0, dchromx=0, dchromy=0; double K2=0.0, *K2ptr; ELEMENT_LIST *context; long i, K2_param=0, type=0, iter, count; double beta_x, alpha_x, eta_x, etap_x; double beta_y, alpha_y, eta_y, etap_y; double K2_min, K2_max; unsigned long unstable; double lastError, presentError; char buffer[256]; log_entry("do_chromaticity_correction"); if (!beamline->matrix || !beamline->twiss0) { if (!beamline->twiss0) beamline->twiss0 = tmalloc(sizeof(*beamline->twiss0)); if (!beamline->elem_twiss) { ELEMENT_LIST *eptr; eptr = beamline->elem_twiss = &(beamline->elem); while (eptr) { if (eptr->type==T_RECIRC) beamline->elem_twiss = beamline->elem_recirc = eptr; eptr = eptr->succ; } } if (beamline->matrix) { free_matrices(beamline->matrix); free(beamline->matrix); beamline->matrix = NULL; } beamline->matrix = compute_periodic_twiss(&beta_x, &alpha_x, &eta_x, &etap_x, beamline->tune, &beta_y, &alpha_y, &eta_y, &etap_y, beamline->tune+1, beamline->elem_twiss, clorb, run, &unstable, NULL, NULL); beamline->twiss0->betax = beta_x; beamline->twiss0->alphax = alpha_x; beamline->twiss0->phix = 0; beamline->twiss0->etax = eta_x; beamline->twiss0->etapx = etap_x; beamline->twiss0->betay = beta_y; beamline->twiss0->alphay = alpha_y; beamline->twiss0->phiy = 0; beamline->twiss0->etay = eta_y; beamline->twiss0->etapy = etap_y; propagate_twiss_parameters(beamline->twiss0, beamline->tune, beamline->waists, NULL, beamline->elem_twiss, run, clorb, beamline->couplingFactor); } else if (beamline->matrix->order<2) { if (beamline->matrix) { free_matrices(beamline->matrix); free(beamline->matrix); beamline->matrix = NULL; } beamline->matrix = full_matrix(beamline->elem_twiss, run, 2); } if (!(M = beamline->matrix) || !M->C || !M->R || !M->T) bombElegant("something wrong with transfer map for beamline (do_chromaticity_correction.1)", NULL); computeChromaticities(&chromx0, &chromy0, NULL, NULL, NULL, NULL, beamline->twiss0, beamline->elast->twiss, M); if (verbosityLevel>0) { fprintf(stdout, "\nAdjusting chromaticities:\n"); fflush(stdout); fprintf(stdout, "initial chromaticities: %e %e\n", chromx0, chromy0); fflush(stdout); } presentError = DBL_MAX; for (iter=0; iter<chrom->n_iterations; iter++) { K2_max = -(K2_min = DBL_MAX); dchromx = chrom->chromx - chromx0; dchromy = chrom->chromy - chromy0; if (chrom->tolerance>0 && chrom->tolerance>fabs(dchromx) && chrom->tolerance>fabs(dchromy) ) break; lastError = presentError; presentError = sqr(dchromx)+sqr(dchromy); if (iter && presentError>lastError) { fprintf(stdout, "Error increasing---reducing gain\n"); fflush(stdout); chrom->correction_fraction /= 10; } if (chrom->use_perturbed_matrix) computeChromCorrectionMatrix(run, beamline, chrom); chrom->dchrom->a[0][0] = dchromx; chrom->dchrom->a[1][0] = dchromy; m_mult(chrom->dK2, chrom->T, chrom->dchrom); for (i=0; i<chrom->n_families; i++) { if (isnan(chrom->correction_fraction*chrom->dK2->a[i][0]) || isinf(chrom->correction_fraction*chrom->dK2->a[i][0])) break; } if (i!=chrom->n_families) { fprintf(stdout, "Unable to correct chromaticity---diverged\n"); fflush(stdout); return 0; } for (i=0; i<chrom->n_families; i++) { context = NULL; count = 0; while ((context=find_element(chrom->name[i], &context, beamline->elem_twiss))) { if (count==0 && (K2_param = confirm_parameter("K2", context->type))<0) { fprintf(stdout, "error: element %s doesn't have K2 parameter\n", context->name); fflush(stdout); exitElegant(1); } if (!(K2ptr = (double*)(context->p_elem + entity_description[context->type].parameter[K2_param].offset))) bombElegant("K2ptr NULL in setup_chromaticity_correction", NULL); K2 = (*K2ptr += chrom->correction_fraction*chrom->dK2->a[i][0]); if (chrom->strengthLimit>0 && chrom->strengthLimit<fabs(K2)) { K2 = *K2ptr = SIGN(K2)*chrom->strengthLimit; } sprintf(buffer, "%s#%ld.K2", context->name, context->occurence); rpn_store(K2, NULL, rpn_create_mem(buffer, 0)); if (K2>K2_max) K2_max = K2; if (K2<K2_min) K2_min = K2; if (context->matrix) { free_matrices(context->matrix); free(context->matrix); context->matrix = NULL; } compute_matrix(context, run, NULL); type = context->type; count++; /* fprintf(stdout, "new value of %s#%ld[K2] is %.15lg 1/m^3\n", chrom->name[i], context->occurence, K2); fflush(stdout); */ } if (verbosityLevel>1) { fprintf(stdout, "Change for family %ld (%ld sextupoles): %e\n", i, count, chrom->correction_fraction*chrom->dK2->a[i][0]); fflush(stdout); } if (alter_defined_values) change_defined_parameter(chrom->name[i], K2_param, type, K2, NULL, LOAD_FLAG_ABSOLUTE); } if (beamline->links) { /* rebaseline_element_links(beamline->links, run, beamline); */ assert_element_links(beamline->links, run, beamline, STATIC_LINK+DYNAMIC_LINK+(alter_defined_values?LINK_ELEMENT_DEFINITION:0)); } if (beamline->matrix) { free_matrices(beamline->matrix); free(beamline->matrix); beamline->matrix = NULL; } M = beamline->matrix = compute_periodic_twiss(&beta_x, &alpha_x, &eta_x, &etap_x, beamline->tune, &beta_y, &alpha_y, &eta_y, &etap_y, beamline->tune+1, beamline->elem_twiss, clorb, run, &unstable, NULL, NULL); beamline->twiss0->betax = beta_x; beamline->twiss0->alphax = alpha_x; beamline->twiss0->phix = 0; beamline->twiss0->etax = eta_x; beamline->twiss0->etapx = etap_x; beamline->twiss0->betay = beta_y; beamline->twiss0->alphay = alpha_y; beamline->twiss0->phiy = 0; beamline->twiss0->etay = eta_y; beamline->twiss0->etapy = etap_y; if (!M || !M->C || !M->R || !M->T) bombElegant("something wrong with transfer map for beamline (do_chromaticity_correction.2)", NULL); computeChromaticities(&chromx0, &chromy0, NULL, NULL, NULL, NULL, beamline->twiss0, beamline->elast->twiss, M); beamline->chromaticity[0] = chromx0; beamline->chromaticity[1] = chromy0; if (verbosityLevel>0) { fprintf(stdout, "resulting chromaticities: %e %e\n", chromx0, chromy0); fprintf(stdout, "min, max sextupole strength: %e %e 1/m^2\n", K2_min, K2_max); fflush(stdout); } } if (fp_sl && last_iteration) { for (i=0; i<chrom->n_families; i++) { context = NULL; while ((context=find_element(chrom->name[i], &context, beamline->elem_twiss))) { if (( K2_param = confirm_parameter("K2", context->type))<0) bombElegant("confirm_parameter doesn't return offset for K2 parameter.\n", NULL); fprintf(fp_sl, "%ld %e %s\n", step, *((double*)(context->p_elem + entity_description[context->type].parameter[K2_param].offset)), chrom->name[i]); } } fflush(fp_sl); } propagate_twiss_parameters(beamline->twiss0, beamline->tune, beamline->waists, NULL, beamline->elem_twiss, run, clorb, beamline->couplingFactor); log_exit("do_chromaticity_correction"); if (chrom->tolerance>0 && (chrom->tolerance<fabs(dchromx) || chrom->tolerance<fabs(dchromy)) && chrom->exit_on_failure) { fprintf(stdout, "Chromaticity correction failure---exiting!\n"); exitElegant(1); } return 1; }
int spai_line (matrix *A, int col, int spar, int lower_diag, int upper_diag, double tau, matrix *M) { int s,nbq,nnz,dimr,block_width; double scalar_resnorm,block_resnorm,adjust_epsilon; int i,index,pe,len,ierr; int row_address; int *rptr; double *aptr; int j, k, ptr, low_c, up_c, ccol, row; int rlen; int *buf; int *rbuf; double *vbuf; double comp_max, tau_limit = 1 - tau; block_width = A->block_sizes[col]; adjust_epsilon = epsilon*sqrt((double) block_width); if (spar == 1) /* mark elements depending on tau parameter */ { comp_max = 0; /* find maximum in column resp. row if transposed */ for (j=0; j<A->lines->len[col]; j++) { ptr = A->lines->ptrs[col][j]; if (comp_max < fabs( A->lines->A[col][j])) comp_max = fabs( A->lines->A[col][j]); } /* keep diagonal and elements about fraction of maximum */ for (i=0, j=0; j<A->lines->len[col]; j++) { ptr = A->lines->ptrs[col][j]; if (ptr == col + A->my_start_index || fabs(A->lines->A[col][j]/comp_max) > tau_limit) { n1[i] = A->block_sizes[j]; J->ptr[i++] = ptr; } } J->len = i; J->slen = i; dimr = nnz = 0; } else if (spar == 2) /* set diagonals - mind switching cols and rows */ { if ((low_c = col-upper_diag) < 0) low_c = 0; if ((up_c = col+lower_diag) > A->n-1) up_c = A->n-1; for (i=0, j=low_c; j<=up_c; j++,i++) { J->ptr[i] = j; n1[i] = A->block_sizes[j]; } J->len = i; J->slen = i; dimr = nnz = 0; } else /* initial sparsity diagonal */ { J->ptr[0] = col; J->len = 1; J->slen = block_width; n1[0] = block_width; dimr = nnz = 0; } /* compute I */ getrows(A,M,J,I); copyvv(J,J_tilde); for (s=0, nbq = 0, TAU_ptr[0] = 0, /* effectively infinity */ scalar_resnorm=block_resnorm=1000000*epsilon; (s < nbsteps); s++, nbq++) { com_server(A,M); full_matrix(A,M,max_dim, Ahat); n2[s] = I->slen - dimr; /* compute solution -> x, residual, and update QR */ if ((ierr = qr(A,col,nbq,dimr)) != 0) return ierr; nnz = J->len; dimr = J->slen; /* is solution good enough? */ /* Use Froebenius norm */ convert_to_block (res,resb,col,I->ptr,A,max_dim,I->len); block_resnorm = frobenius_norm(resb,block_width,I->slen); if (debug) { fprintf(fptr_dbg," s=%d col=%d of %d block_resnorm=%12.4le\n", s,col,A->n,block_resnorm); fflush(fptr_dbg); } if (spar == 1 /* row population with tau parameter */ || spar == 2) break; /* fixed diagonals - no further ado */ if (block_resnorm <= adjust_epsilon) break; /* Don't bother with last augment_sparsity */ if (s == (nbsteps-1)) break; if (! augment_sparsity(A,M,col,maxapi,block_resnorm)) break; getrows(A,M, J_tilde,I_tilde); deleter(I,I_tilde,A); if (! append(J,J_tilde)) break; /* J <- J U J_tilde */ if (! append(I,I_tilde)) break; /* I <- I U I_tilde */ } if (block_resnorm > adjust_epsilon && spar == 0) { num_bad_cols++; if (message) { fprintf(message, "could not meet tol, col=%d resnorm = %le, adjust_epsilon = %le\n", col+1, block_resnorm/sqrt((double) block_width), adjust_epsilon); fflush(message); } } if (resplot_fptr) { for (i=0; i<block_width; i++) { if (block_resnorm <= adjust_epsilon) block_flag = " "; else block_flag = "*"; scalar_resnorm = frobenius_norm(&res[i*max_dim],1,I->slen); if (scalar_resnorm <= epsilon) scalar_flag = " "; else scalar_flag = "*"; fprintf(resplot_fptr,"%6d %5.3lf %s %6d %5.3lf %s\n", start_col+i, scalar_resnorm, scalar_flag, col, block_resnorm/sqrt((double) block_width), block_flag); } start_col += block_width; } /* current solution in x, up to nnz, written to M(k,:) */ /* convert x to block structure */ convert_to_block (x,xb,col,J->ptr,A,max_dim,nnz); put_Mline(A,M, col, J->ptr, xb, nnz, J->slen); for (i=0; i<nbsteps; i++) { if (Qlist[i]) { free(Qlist[i]); Qlist[i] = NULL; } else break; } return 0; }