Example #1
0
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);
  }
Example #2
0
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;
  }
Example #3
0
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;
}