Example #1
0
void pitch_matrices(VMATRIX *M, double pitch)
/* transform element matrix to reflect pitching of element (rotation
 * about horizontal transverse axis)
 */
{
  static VMATRIX input, output;
  static long initialized=0;
  static VMATRIX Mr;

  if (pitch==0)
    return;

  if (!initialized) {
    long i;
    initialized = 1;
    initialize_matrices(&input, 1);
    initialize_matrices(&output, 1);
    initialize_matrices(&Mr, M->order);
    for (i=0; i<6; i++)
      input.R[i][i] = output.R[i][i] = 1;
  }
  
  input.C[3] = pitch;
  output.C[3] = -pitch;

  concat_matrices(&Mr, M, &input, 0);
  concat_matrices(M, &output, &Mr, 0);
}
Example #2
0
void yaw_matrices(VMATRIX *M, double yaw)
/* transform element matrix to reflect yawing of element (rotation
 * about vertical axis)
 */
{
  static VMATRIX input, output;
  static long initialized=0;
  static VMATRIX Mr;

  if (yaw==0)
    return;

  if (!initialized) {
    long i;
    initialized = 1;
    initialize_matrices(&input, 1);
    initialize_matrices(&output, 1);
    initialize_matrices(&Mr, M->order);
    for (i=0; i<6; i++)
      input.R[i][i] = output.R[i][i] = 1;
  }
  
  input.C[1] = yaw;
  output.C[1] = -yaw;
  concat_matrices(&Mr, M, &input, 0);
  concat_matrices(M, &output, &Mr, 0);
}
Example #3
0
microseconds MatrixMul::mult_blas(const Args & args, std::mt19937 & gen)
{
	std::cout << "Test: BLAS ";
	const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args);

	uint32_t m, k, l;
	get_matrix_sizes(cur_args, m, k, l);

	double * A = new double[m * k];
	double * B = new double[k * l];
	double * C = new double[m * l];

	initialize_matrices(A, A + m*k, B, B + k*l, gen, cur_args);

	auto start = std::chrono::high_resolution_clock::now();
	cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, l, k,
				1.0, A, k, B, l, 0.0, C, l);
	auto end = std::chrono::high_resolution_clock::now();

	if( args.test ) {
		verify_results(C, C + m*l);
	}

	auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start);
	std::cout << time.count() << std::endl;

	delete[] A;
	delete[] B;
	delete[] C;

	return time;
}
Example #4
0
int main()
{

	int a[3][3];
	int b[3][3];
	int c[3][3];

	//Q2: define pointers (5)
	//Define pointers ap, bp, and cp to the matrices that are defined above

	//CODE HERE
	int *ap = a, *bp = b, *cp = c;
	

	//Uncomment these once you've defined your matrices

	initialize_matrices(ap, bp, cp);

	printf("Matrix a:\n");
	fill_matrix(ap);

	printf("Matrix b:\n");
	fill_matrix(bp);

	add_matrices(ap, bp, cp);

	print_sum_matrix(cp);

	

	return 0;
}
Example #5
0
microseconds MatrixMul::blitz(const Args & args, std::mt19937 & gen)
{
	std::cout << "Test: blitz++ ";

	const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args);
	uint32_t m, k, l;
	get_matrix_sizes(cur_args, m, k, l);

	blitz::Array<double, 2> C(m, l), B(k, l), A(m, k);
	initialize_matrices(A.begin(), A.end(), B.begin(), B.end(), gen, cur_args);

	auto start = std::chrono::high_resolution_clock::now();
    blitz::firstIndex i;
    blitz::secondIndex j;
    blitz::thirdIndex n;
    C = blitz::sum(A(i,n) * B(n,j), n);
	auto end = std::chrono::high_resolution_clock::now();

	if( args.test ) {
		verify_results(C.begin(), C.end());
	}

	auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start);
	std::cout << time.count() << std::endl;
	return time;
}
Example #6
0
int main()
{

	int a[3][3];
	int b[3][3];
	int c[3][3];

	//Q2: define pointers (5)
	//Define pointers ap, bp, and cp to the matrices that are defined above

	//SOLUTION CODE
	int* ap = &a[0][0];
	int* bp = &b[0][0];
	int* cp = &c[0][0];
	//SOLUTION CODE

	initialize_matrices(ap, bp, cp);

	printf("Matrix a:\n");
	fill_matrix(ap);

	printf("Matrix b:\n");
	fill_matrix(bp);

	add_matrices(ap, bp, cp);

	print_sum_matrix(cp);

	return 0;
}
int main(int argc, char **argv)
{

	/*char logfile_name[100];
	FILE *logfile_handle;*/

	//n = 500;
	if(argc > 1){
		n = atoi(argv[1]);
	}

	//sprintf(logfile_name, "logfile_dgemm.txt");
	//logfile_handle = freopen(logfile_name, "w", stdout);

	mem_size = n * n * sizeof(double);
	a = (double*)malloc(mem_size);
	b = (double*)malloc(mem_size);
	c = (double*)malloc(mem_size);
	if(0 == a || 0 == b || 0 == c){
		printf("memory allocation failed");
		return 0;
	}

	/* matrices initialisation */
        initialize_matrices();


	/* naive matrix multiplication */  
        optimized_matrix_multiplication_algo();


	return(0);
}
std::auto_ptr<MAST::FlutterSolutionBase>
MAST::TimeDomainFlutterSolver::analyze(const Real v_ref,
                                       const MAST::FlutterSolutionBase* prev_sol) {
    RealMatrixX a, b;
    
    libMesh::out
    << " ====================================================" << std::endl
    << "Eigensolution for V = "
    << std::setw(10) << v_ref << std::endl;
    
    initialize_matrices(v_ref, a, b);
    LAPACK_DGGEV ges;
    ges.compute(a, b);
    ges.scale_eigenvectors_to_identity_innerproduct();

    
    MAST::TimeDomainFlutterSolution* root =
    new MAST::TimeDomainFlutterSolution;
    root->init(*this, v_ref, flight_condition->ref_chord, ges);
    
    if (prev_sol)
        root->sort(*prev_sol);

    libMesh::out
    << "Finished Eigensolution" << std::endl
    << " ====================================================" << std::endl;
    
    
    return std::auto_ptr<MAST::FlutterSolutionBase> (root);
}
Example #9
0
/*---------------------------------------------------------------------------
 *
 * Compute matrix product using recursive tiling.
 *
 * Input
 *   int argc        - length of argv[] array
 *   char* argv[]    - pointer to command line parameter array
 *   int verbosity   - program verification: verbosity > 0 gives more output
 *   char* order     - string indicating loop order, e.g., "ijk" or "jki"
 *
 * Output
 *   double          - elapsed time for product computation
 */
double multiply_by_recursive_blocks( int argc, char* argv[], int verbosity,
                                     char* order )
{
    int rows, cols, mids, block_size;
    double **a, **b, **c;
    double t1, t2;
    double sec;
    double gflop_count;

    /*
     * process command line arguments
     */
    rows = atoi( argv[0] );
    mids = atoi( argv[1] );
    cols = atoi( argv[2] );
    block_size = atoi( argv[3] );
    gflop_count = 2.0 * rows * mids * cols / 1.0e9;

    if ( verbosity > 0 )
    {
        printf( "Recursive blocks(%3s): rows = %d, mids = %d, columns = %d\n",
                order, rows, mids, cols );
        printf( "block size = %d\n", block_size );
    }

    /*
     * allocate and initialize matrices
     */
    a = (double**) allocateMatrix( rows, mids );
    b = (double**) allocateMatrix( mids, cols );
    c = (double**) allocateMatrix( rows, cols );
    initialize_matrices( a, b, c, rows, cols, mids, verbosity );

    /*
     * compute product
     */
    t1 = wtime();
    mm_rec( c, a, b, 0, 0, 0, 0, 0, 0, rows, mids, cols, cols, block_size );
    t2 = wtime();
    sec = t2 - t1;

    if ( verbosity > 1 )
        printf( "checksum = %f\n", checksum( c, rows, cols ) );

    printf( "blocks(%3s): %6.3f secs %6.3f gflops ",
            order, sec, gflop_count / sec );
    printf( "( %5d x %5d x %5d ) ( %6d )\n", rows, mids, cols, block_size );

    /*
     * clean up
     */
    deallocateMatrix( a );
    deallocateMatrix( b );
    deallocateMatrix( c );

    return t2 - t1;
}
Example #10
0
microseconds MatrixMul::plain_call(const Args & args, std::mt19937 & gen)
{
	std::cout << "Test: plain call ";

	const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args);
	uint32_t m, k, l;
	get_matrix_sizes(cur_args, m, k, l);
	double * A = new double[m*k];
	double * B = new double[k*l];
	double * C = new double[m*l];

	/**
		Initialize
	**/
	initialize_matrices(A, A + m*k, B, B + k*l, gen, cur_args);

	/**
		Compute
	**/
	auto start = std::chrono::high_resolution_clock::now();

	for(uint32_t i = 0; i < m;++i) {

		for(uint32_t n = 0; n < l; ++n) {
			C[i*l + n] = A[i*k] * B[n];
		}

		for(uint32_t j = 1; j < k; ++j) {
			for(uint32_t n = 0; n < l; ++n) {
				C[i*l + n] += A[i*k + j] * B[j*l + n];
			}
		}
	}

	auto end = std::chrono::high_resolution_clock::now();

	if( args.test ) {
		verify_results(C, C + m*l);
	}

	delete[] A;
	delete[] B;
	delete[] C;

	auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start);
	std::cout << time.count() << std::endl;
	return time;
}
Example #11
0
VMATRIX *rotation_matrix(double tilt)
{
    VMATRIX *Rot;
    double sin_tilt, cos_tilt;

    log_entry("rotation_matrix");

    if (fabs(tilt-PI/2)<1e-12) {
        sin_tilt = 1;
        cos_tilt = 0;
        }
    else if (fabs(tilt-PI)<1e-12) {
        sin_tilt = 0;
        cos_tilt = -1;
        }
    else {
        sin_tilt = sin(tilt);
        cos_tilt = cos(tilt);
        }

    Rot = tmalloc(sizeof(*Rot));
    initialize_matrices(Rot, 1);

    /* Rotation matrix for (x, y) */
    Rot->R[0][0] =  cos_tilt ;
    Rot->R[0][2] =  sin_tilt ;
    Rot->R[2][0] = -sin_tilt ;
    Rot->R[2][2] =  cos_tilt ;

    /* Rotation matrix for (x', y') */
    Rot->R[1][1] =  cos_tilt ;
    Rot->R[1][3] =  sin_tilt ;
    Rot->R[3][1] = -sin_tilt ;
    Rot->R[3][3] =  cos_tilt ;

    Rot->R[4][4] = Rot->R[5][5] = 1;

    log_exit("rotation_matrix");
    return(Rot);
    }
Example #12
0
microseconds MatrixMul::mult_blaze(const Args & args, std::mt19937 & gen)
{
	std::cout << "Test: Blaze ";
	const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args);
	uint32_t m, k, l;
	get_matrix_sizes(cur_args, m, k, l);

	blaze::DynamicMatrix<double, blaze::rowMajor> A(m, k), B(k, l), C(m, l);
	initialize_matrices(A.data(), A.data() + m*k, B.data(), B.data() + k*l, gen, cur_args);

	auto start = std::chrono::high_resolution_clock::now();
	C = A * B;
	auto end = std::chrono::high_resolution_clock::now();

	if( args.test ) {
		verify_results(C.data(), C.data() + m*l);
	}

	auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start);
	std::cout << time.count() << std::endl;
	return time;
}
Example #13
0
microseconds MatrixMul::boost_ublas(const Args & args, std::mt19937 & gen)
{
	std::cout << "Test: boost uBLAS ";
	const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args);
	uint32_t m, k, l;
	get_matrix_sizes(cur_args, m, k, l);

	boost::numeric::ublas::matrix<double> A(m, k), B(k, l), C(m, l);
	initialize_matrices(A.data().begin(), A.data().end(), B.data().begin(), B.data().end(), gen, cur_args);

	auto start = std::chrono::high_resolution_clock::now();
	noalias(C) = prod( A, B );
	auto end = std::chrono::high_resolution_clock::now();

	if( args.test ) {
		verify_results(C.data().begin(), C.data().end());
	}

	auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start);
	std::cout << time.count() << std::endl;
	return time;
}
Example #14
0
microseconds MatrixMul::op_overl(const Args & args, std::mt19937 & gen)
{
	std::cout << "Test: operator overloading ";

	const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args);
	uint32_t m, k, l;
	get_matrix_sizes(cur_args, m, k, l);

	MatrixMul::Matrix<double> A(m,k), B(k,l), C(m,l);

	/**
		Initialize
	**/
	initialize_matrices(A.data, A.data + m*k, B.data, B.data + k*l, gen, cur_args);

	/**
		Compute
	**/
	auto start = std::chrono::high_resolution_clock::now();

	C = A*B;

	auto end = std::chrono::high_resolution_clock::now();

	/*if( args.test ) {
		verify_results(C, C + m*l);
	}

	delete[] A;
	delete[] B;
	delete[] C;*/

	auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start);
	std::cout << time.count() << std::endl;
	return time;
}
void run_no_events()
{
  initialize_matrices() ;
  multiply_matrices() ;
}
Example #16
0
/*---------------------------------------------------------------------------
 *
 * Compute matrix product using tiling.  The loop order used for the tile
 * products is specified in string variable "mode".
 *
 * Input
 *   int argc        - length of argv[] array
 *   char* argv[]    - pointer to command line parameter array
 *   int verbosity   - program verification: verbosity > 0 gives more output
 *   char* order     - string indicating loop order, e.g., "ijk" or "jki"
 *
 * Output
 *   double          - elapsed time for product computation
 */
double multiply_by_tiles( int argc, char* argv[], int verbosity, char* order )
{
    int rows, cols, mids;
    int rows_per_tile, cols_per_tile, mids_per_tile;
    int row_start, row_end;
    int col_start, col_end;
    int mid_start, mid_end;
    double **a, **b, **c;
    double t1, t2;
    double sec;
    double gflop_count;

    /*
     * process command line arguments
     */
    rows = atoi( argv[0] );
    mids = atoi( argv[1] );
    cols = atoi( argv[2] );
    rows_per_tile = atoi( argv[3] );
    mids_per_tile = atoi( argv[4] );
    cols_per_tile = atoi( argv[5] );
    gflop_count = 2.0 * rows * mids * cols / 1.0e9;

    if ( verbosity > 0 )
    {
        printf( "Tiles(%3s): rows = %d, mids = %d, columns = %d\n",
                order, rows, mids, cols );
        printf( "block rows = %d, mids = %d, columns = %d\n",
                rows_per_tile, mids_per_tile, cols_per_tile );
    }

    /*
     * allocate and initialize matrices
     */
    a = (double**) allocateMatrix( rows, mids );
    b = (double**) allocateMatrix( mids, cols );
    c = (double**) allocateMatrix( rows, cols );
    initialize_matrices( a, b, c, rows, cols, mids, verbosity );

    /*
     * compute product
     */
    t1 = wtime();
    for ( row_start = 0; row_start < rows; row_start += rows_per_tile )
    {
        row_end = row_start + rows_per_tile - 1;
        if ( row_end >= rows ) row_end = rows - 1;
        for ( col_start = 0; col_start < cols; col_start += cols_per_tile )
        {
            col_end = col_start + cols_per_tile - 1;
            if ( col_end >= cols ) col_end = cols - 1;
            for ( mid_start = 0; mid_start < mids; mid_start += mids_per_tile )
            {
                mid_end = mid_start + mids_per_tile - 1;
                if ( mid_end >= mids ) mid_end = mids - 1;
                do_product( a, b, c, row_start, row_end, col_start,
                            col_end, mid_start, mid_end );
            }
        }
    }
    t2 = wtime();
    sec = t2 - t1;

    if ( verbosity > 1 )
        printf( "checksum = %f\n", checksum( c, rows, cols ) );

    printf( "tiles(%3s):  %6.3f secs %6.3f gflops ",
            order, sec, gflop_count / sec );
    printf( "( %5d x %5d x %5d ) ( %4d x %4d x %4d )\n",
            rows, mids, cols, rows_per_tile, mids_per_tile,
            cols_per_tile );

    /*
     * clean up
     */
    deallocateMatrix( a );
    deallocateMatrix( b );
    deallocateMatrix( c );

    return t2 - t1;
}
Example #17
0
void tilt_matrices(VMATRIX *M, double tilt)
{
    static VMATRIX Rot, IRot;
    static long initialized=0;
    VMATRIX Mr;
    double sin_tilt, cos_tilt;


    log_entry("tilt_matrices");
    
    if (tilt==0) {
        log_exit("tilt_matrices");
        return;
        }

    if (!initialized) {
        initialized = 1;
        initialize_matrices(&Rot, 1);
        initialize_matrices(&IRot, 1);
        }

    initialize_matrices(&Mr, M->order);
    
    if (fabs(tilt-PI/2)<1e-12) {
        sin_tilt = 1;
        cos_tilt = 0;
        }
    else if (fabs(tilt+PI/2)<1e-12) {
        sin_tilt = -1;
        cos_tilt = 0;
        }
    else if (fabs(tilt-PI)<1e-12 || fabs(tilt+PI)<1e-12) {
        sin_tilt = 0;
        cos_tilt = -1;
        }
    else {
        sin_tilt = sin(tilt);
        cos_tilt = cos(tilt);
        }

    /* Rotation matrix for (x, y) */
    IRot.R[0][0] =   Rot.R[0][0] =  cos_tilt ;
    IRot.R[0][2] = -(Rot.R[0][2] =  sin_tilt);
    IRot.R[2][0] = -(Rot.R[2][0] = -sin_tilt);
    IRot.R[2][2] =   Rot.R[2][2] =  cos_tilt ;

    /* Rotation matrix for (x', y') */
    IRot.R[1][1] =   Rot.R[1][1] =  cos_tilt ;
    IRot.R[1][3] = -(Rot.R[1][3] =  sin_tilt);
    IRot.R[3][1] = -(Rot.R[3][1] = -sin_tilt);
    IRot.R[3][3] =   Rot.R[3][3] =  cos_tilt ;

    IRot.R[4][4] = IRot.R[5][5] = Rot.R[4][4]  = Rot.R[5][5]  = 1;

    concat_matrices(&Mr,     M, &Rot, 0);
    concat_matrices(M  , &IRot, &Mr , 0);

    free_matrices(&Mr); 

    log_exit("tilt_matrices");
    }
Example #18
0
/*---------------------------------------------------------------------------
 *
 * Compute matrix product using BLAS routine DGEMM.
 *
 * Input
 *   int argc        - length of argv[] array
 *   char* argv[]    - pointer to command line parameter array
 *   int verbosity   - program verification: verbosity > 0 gives more output
 *
 * Output
 *   double          - elapsed time for product computation
 */
double multiply_by_blas( int argc, char* argv[], int verbosity )
{
    int rows, cols, mids;
    double **a, **b, **c;
    double t1, t2;
    double sec;
    double gflop_count;

    /*
     * process command line arguments
     */
    rows = atoi( argv[0] );
    mids = atoi( argv[1] );
    cols = atoi( argv[2] );
    gflop_count = 2.0 * rows * mids * cols / 1.0e9;

    if ( verbosity > 0 )
    {
        printf( "BLAS: rows = %d, mids = %d, columns = %d\n",
                rows, mids, cols );
    }

    /*
     * allocate and initialize matrices
     */
    a = (double**) allocateMatrix( rows, mids );
    b = (double**) allocateMatrix( mids, cols );
    c = (double**) allocateMatrix( rows, cols );
    initialize_matrices( a, b, c, rows, cols, mids, verbosity );

    /*
     * compute product: There is an implicit matrix transpose when
     * passing from Fortran to C and vice-versa.  To compute C :=
     * alpha * A * B + beta * C we use dgemm() to compute C' := alpha
     * * B' * A' + beta * C'.  The first two arguments to dgemm() are
     * 'N' indicating we don't want a transpose in addition to the
     * implicit one.  The matrices A and B are passed in reverse order
     * so dgemm() receives (after the implicit transpose) B' and A'.
     * Arguments 3 and 4 are the dimensions of C' and argument 5 is
     * the column dimension of B' (and the row dimension of A').
     */
    t1 = wtime();
    dgemm( 'N', 'N', cols, rows, mids, 1.0, &b[0][0], cols, &a[0][0], mids, 
           0.0, &c[0][0], cols );
    t2 = wtime();
    sec = t2 - t1;

    if ( verbosity > 1 )
        printf( "checksum = %f\n", checksum( c, rows, cols ) );

    printf( "BLAS:        %6.3f secs %6.3f gflops ( %5d x %5d x %5d )\n",
            sec, gflop_count / sec, rows, mids, cols );

    /*
     * clean up
     */
    deallocateMatrix( a );
    deallocateMatrix( b );
    deallocateMatrix( c );

    return t2 - t1;
}
Example #19
0
void computeHigherOrderChromaticities(LINE_LIST *beamline, double *clorb, RUN *run,
				      long concatOrder, double deltaStep, long deltaPoints,
                                      long quickMode)
{
#define MAX_NDELTA_VALUES 101   /* must be at least 5 */
  double trace[2][MAX_NDELTA_VALUES], delta[MAX_NDELTA_VALUES];
  double eta[6];
  double coef[MAX_NDELTA_VALUES], sCoef[MAX_NDELTA_VALUES], chi;
  long i, p;
  double c1;
  VMATRIX M1, M0, *Mp;

  if (deltaPoints>MAX_NDELTA_VALUES)
    bombElegant("too many points for higher-order chromaticity", NULL);
  if (deltaPoints<5)
    deltaPoints = 5;
  if (!(beamline->matrix))
    bombElegant("no matrix for beamline (computeHigherOrderChromaticities)", NULL);
  
  beamline->chrom2[0] = beamline->chrom2[1] = 0;
  beamline->chrom3[0] = beamline->chrom3[1] = 0;
  initialize_matrices(&M0, 1);
  initialize_matrices(&M1, concatOrder);
  
  eta[0] = beamline->twiss0->etax;
  eta[1] = beamline->twiss0->etapx;
  eta[2] = beamline->twiss0->etay;
  eta[3] = beamline->twiss0->etapy;
  eta[4] = 0;
  eta[5] = 1;
  for (p=0; p<deltaPoints; p++) {
    delta[p] = (p-(deltaPoints/2+1))*deltaStep;
    for (i=0; i<6; i++) {
      M0.C[i] = (clorb?clorb[i]:0)+delta[p]*eta[i] +
	(i<4? sqr(delta[p])*beamline->eta2[i] + pow3(delta[p])*beamline->eta3[i] : 0);
      M0.R[i][i] = 1;
    }
    if (quickMode)
      concat_matrices(Mp=&M1, beamline->matrix, &M0, 0);
    else
      Mp = append_full_matrix(beamline->elem_twiss, run, &M0, concatOrder);
    for (i=0; i<2; i++)
      /* Tr[0,1][p] is the trace for x,y plane for point p */
      trace[i][p] = Mp->R[2*i][2*i] + Mp->R[2*i+1][2*i+1];
    if (!quickMode) {
      free_matrices(Mp);
      free(Mp);
      Mp = NULL;
    }
  }
  for (i=0; i<2; i++) {
    lsfn(delta, trace[i], NULL, deltaPoints, (long)(MIN(deltaPoints-2,5)), 
         coef, sCoef, &chi, NULL);
    c1 = -coef[1]/(4*PI*sin(PIx2*beamline->tune[i]));
    beamline->chrom2[i] = (
                           2*coef[2]
                           + 8*sqr(PI)*sqr(c1)*cos(PIx2*beamline->tune[i])
                           )/(-4*PI*sin(PIx2*beamline->tune[i]));
    if (quickMode)
      beamline->chrom3[i] = 0;
    else
      beamline->chrom3[i] = (
                             6*coef[3] 
                             - 16*pow3(PI*c1)*sin(PIx2*beamline->tune[i]) 
                             + 24*sqr(PI)*c1*beamline->chrom2[i]*cos(PIx2*beamline->tune[i])
                             )/(-4*PI*sin(PIx2*beamline->tune[i]));
  }
  free_matrices(&M0);
  free_matrices(&M1);
}
Example #20
0
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);
}
void
MAST::NoniterativeUGFlutterSolver::calculate_sensitivity(MAST::FlutterRootBase& root,
                                                         const libMesh::ParameterVector& params,
                                                         const unsigned int i) {
    // make sure that the aero_structural_model is a valid pointer
    libmesh_assert(aero_structural_model);
    
    libMesh::out
    << " ====================================================" << std::endl
    << "UG Sensitivity Solution" << std::endl
    << "   k_red = " << std::setw(10) << root.k_red << std::endl
    << "   V_ref = " << std::setw(10) << root.V << std::endl;
    
    Complex eig = root.root, sens = 0., k_sens = 0., vref_sens = 0., den = 0.;
    
    // matrix to store the sensitivity of constraint wrt kref and vref
    // first row is constraint  f1(k,v) = g = im(lambda)/re(lambda) = 0
    // second row is constraint f2(k,v) = vref*sqrt(re(lambda))-1.  = 0
    RealMatrixX jac;
    
    // residual vector for the sensitivity problem, and total derivative vec
    // first row is for constraint f1(k,v)
    // first row is for constraint f2(k,v)
    RealVectorX res, dsens;
    jac.setZero(2,2);
    res.setZero(2);
    
    // get the sensitivity of the matrices
    ComplexMatrixX mat_A, mat_B, mat_A_sens, mat_B_sens;
    ComplexVectorX v;
    
    // initialize the baseline matrices
    initialize_matrices(root.k_red_ref, root.V_ref, mat_A, mat_B);
    
    // calculate the eigenproblem sensitivity
    initialize_matrix_sensitivity_for_param(params, i,
                                            root.k_red_ref,
                                            root.V_ref,
                                            mat_A_sens,
                                            mat_B_sens);
    
    // the eigenproblem is     A x - lambda B x = 0
    // therefore, the denominator is obtained from the inner product of
    // x^T B x
    // sensitivity is
    //   -dlambda/dp x^T B x = - x^T (dA/dp - lambda dB/dp)
    // or
    //   dlambda/dp = [x^T (dA/dp - lambda dB/dp)]/(x^T B x)
    
    // now calculate the quotient for sensitivity
    // numerator =  ( dA/dp - lambda dB/dp)
    mat_B_sens *= -eig;
    mat_B_sens += mat_A_sens;
    v = mat_B_sens*root.eig_vec_right;
    den = root.eig_vec_left.dot(mat_B*root.eig_vec_right);
    sens = root.eig_vec_left.dot(v)/den;
    
    // sensitivity of f1(k,v) = im(lambda)/re(lambda) = 0
    res(0) =
    sens.imag()/eig.real() - eig.imag()/pow(eig.real(),2) * sens.real();
    // sensitivity of f2(k,v) = vref*sqrt(real(lambda)) - 1 = 0
    res(1) = root.V_ref*0.5*pow(eig.real(),-0.5)*sens.real();
    
    
    // next we need the sensitivity of k_red before we can calculate
    // the sensitivity of flutter eigenvalue
    initialize_matrix_sensitivity_for_reduced_freq(root.k_red_ref,
                                                   root.V_ref,
                                                   mat_A_sens,
                                                   mat_B_sens);
    
    // now calculate the quotient for sensitivity wrt k_red
    // calculate numerator
    mat_B_sens *= -eig;
    mat_B_sens += mat_A_sens;
    v = mat_B_sens*root.eig_vec_right;
    k_sens = root.eig_vec_left.dot(v) / den;
    
    // use this to calculate the partial derivative of f1 wrt k_red
    jac(0,0) =
    k_sens.imag()/eig.real() - eig.imag()/pow(eig.real(),2)*k_sens.real();
    jac(1,0) = root.V_ref*0.5*pow(eig.real(),-0.5)*k_sens.real();
    
    
    // next we need the sensitivity of Vref constraint before we can calculate
    // the sensitivity of flutter eigenvalue
    initialize_matrix_sensitivity_for_V_ref(root.k_red_ref,
                                            root.V_ref,
                                            mat_A_sens,
                                            mat_B_sens);
    
    // now calculate the quotient for sensitivity wrt k_red
    // calculate numerator
    mat_B_sens *= -eig;
    mat_B_sens += mat_A_sens;
    v = mat_B_sens*root.eig_vec_right;
    vref_sens = root.eig_vec_left.dot(v) / den;
    
    // use this to calculate the partial derivative of f2 wrt vref
    jac(0,1) =
    vref_sens.imag()/eig.real() - eig.imag()/pow(eig.real(),2)*vref_sens.real();
    jac(1,1) =
    sqrt(eig.real()) + root.V_ref*0.5*pow(eig.real(),-0.5)*vref_sens.real();

    // now invert the Jacobian to calculate the sensitivity
    dsens = -jac.inverse()*res;
    
    // finally add the correction to the flutter sensitivity
    sens += k_sens * dsens(0) + vref_sens * dsens(1);
    
    // set value in the return root
    root.has_sensitivity_data = true;
    root.root_sens  = sens;
    root.V_sens     = -.5*sens.real()/pow(eig.real(), 1.5);
    
    libMesh::out
    << "Finished UG Sensitivity Solution" << std::endl
    << " ====================================================" << std::endl;
    
}
std::pair<bool, MAST::FlutterSolutionBase*>
MAST::NoniterativeUGFlutterSolver::newton_search(const MAST::FlutterSolutionBase& init_sol,
                                                 const unsigned int root_num,
                                                 const Real tol,
                                                 const unsigned int max_iters) {
    
    std::pair<bool, MAST::FlutterSolutionBase*> rval(false, NULL);
    // assumes that the upper k_val has +ve g val and lower k_val has -ve
    // k_val
    Real k_red, v_ref;
    unsigned int n_iters = 0;
    
    std::auto_ptr<MAST::FlutterSolutionBase> new_sol;

    RealVectorX res, sol, dsol;
    RealMatrixX jac;
    ComplexMatrixX mat_A, mat_B, mat_A_sens, mat_B_sens;
    ComplexVectorX v;

    res.resize(2); sol.resize(2); dsol.resize(2);
    jac.resize(2,2);
    
    // initialize the solution to the values of init_sol
    k_red  = init_sol.get_root(root_num).k_red_ref;
    v_ref  = init_sol.get_root(root_num).V_ref;
    sol(0) = k_red;
    sol(1) = v_ref;

    const MAST::FlutterSolutionBase* prev_sol = &init_sol;
    
    bool if_continue = true;
    
    while (if_continue) {

        // evaluate the residual and Jacobians
        std::auto_ptr<MAST::FlutterSolutionBase> ug_sol =
        this->analyze(k_red, v_ref, prev_sol);

        ug_sol->print(_output);

        // add the solution to this solver
        _insert_new_solution(v_ref, ug_sol.release());
        
        // now get a pointer to the previous solution
        // get the solution from the database for this reduced frequency
        std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
        _flutter_solutions.find(k_red);
        
        libmesh_assert(it != _flutter_solutions.end());
        rval.second = it->second;
        prev_sol = it->second;

        // solve the Newton update problem
        const MAST::FlutterRootBase& root = prev_sol->get_root(root_num);
        Complex eig = root.root, eig_k_red_sens = 0., den = 0., eig_V_ref_sens = 0.;
        
        // initialize the baseline matrices
        initialize_matrices(k_red, v_ref, mat_A, mat_B);
        
        // solve the sensitivity problem
        // first with respect to k_red
        // next we need the sensitivity of k_red before we can calculate
        // the sensitivity of flutter eigenvalue
        initialize_matrix_sensitivity_for_reduced_freq(k_red,
                                                       v_ref,
                                                       mat_A_sens,
                                                       mat_B_sens);
        
        // now calculate the quotient for sensitivity wrt k_red
        // calculate numerator
        mat_B_sens *= -eig;
        mat_B_sens += mat_A_sens;
        v = mat_B_sens*root.eig_vec_right;
        den = root.eig_vec_left.dot(mat_B*root.eig_vec_right);
        eig_k_red_sens = root.eig_vec_left.dot(v) / den;
        
        
        // next, sensitivity wrt V_ref
        initialize_matrix_sensitivity_for_V_ref(k_red,
                                                v_ref,
                                                mat_A_sens,
                                                mat_B_sens);

        // now calculate the quotient for sensitivity wrt V_ref
        // calculate numerator
        mat_B_sens *= -eig;
        mat_B_sens += mat_A_sens;
        v = mat_B_sens*root.eig_vec_right;
        den = root.eig_vec_left.dot(mat_B*root.eig_vec_right);
        eig_V_ref_sens = root.eig_vec_left.dot(v) / den;

        // residual
        res(0) = eig.imag()/eig.real();
        res(1) = v_ref*sqrt(eig.real()) - 1.;
        
        // Jacobian
        jac(0,0) = eig_k_red_sens.imag()/eig.real() -
        eig.imag()*pow(eig.real(),-2)*eig_k_red_sens.real();
        jac(0,1) = eig_V_ref_sens.imag()/eig.real() -
        eig.imag()*pow(eig.real(),-2)*eig_V_ref_sens.real();
        jac(1,0) = 0.5*v_ref*pow(eig.real(),-0.5)*eig_k_red_sens.real();
        jac(1,1) = sqrt(eig.real()) + 0.5*v_ref*pow(eig.real(),-0.5)*eig_V_ref_sens.real();

        /*std::auto_ptr<MAST::FlutterSolutionBase> ug_dsol =
        this->analyze(k_red+.001, v_ref, prev_sol);
        Complex deig = ug_dsol->get_root(root_num).root;
        deig -= eig;
        deig /= .001;
        
        std::cout << "fd deig/dk:  " << deig << std::endl;
        std::cout << "analytical: " << eig_k_red_sens << std::endl;
        
        ug_dsol.reset(this->analyze(k_red, v_ref+.001, prev_sol).release());
        deig = ug_dsol->get_root(root_num).root;
        deig -= eig;
        deig /= .001;
        
        std::cout << "fd deig/dV:  " << deig << std::endl;
        std::cout << "analytical: " << eig_V_ref_sens << std::endl;*/

        // now calculate the updates
        //     r0 + J *dx = 0
        // =>  dx = - inv(J) * r0
        // =>  x1 = x0 + dx
        
        dsol = -jac.inverse()*res;
        sol += dsol;
        
        // get the updated parameter values
        k_red = sol(0);
        v_ref = sol(1);
        
        // increment the iteration counter
        n_iters++;
        
        // set the flag
        if (fabs(root.g) < tol) {
            rval.first = true;
            return rval;
        }
        
        if (n_iters >= max_iters)
            if_continue = false;
    }
    
    // return false, along with the latest sol
    rval.first = false;
    
    return rval;
}