Beispiel #1
0
/*
 Create the system admittance matrix from power system data. Note that this function is called transparently from GetPSFromFile once power system data has been populated (if the file read is successful).
 */
int CreateYBus(PS ps, int *ids){

	int i, from, to, num_buses = ps->num_buses, num_branches = ps->num_branches, nnz = num_buses + 2*num_branches;
	double r, x, b;
	double _Complex y, *diags = malloc(num_buses*sizeof(double _Complex));
	
	//allocate a ybus
	cs_ci *ybus = cs_ci_spalloc(num_buses, num_buses, nnz, 1, 1), *ybus_comp, *ybus_comp_t;
	
	//check memory
	if(!ybus) return 1;
		
	//loop through ybus branches
	for(i=0; i<num_branches; i++)
	{
		//get branch from/to bus indices
		from = ps->branches[i].from_index;
		to = ps->branches[i].to_index;
	
		//determine line admittance
		r = ps->branches[i].r;
		x = ps->branches[i].x;
		b = ps->branches[i].b;		
		y = (1.0+0.0*I)/(r+x*I);

		//add off-diagonals to ybus and increment diagonal entries
		cs_ci_entry(ybus, from, to, -y);
		cs_ci_entry(ybus, to, from, -y);
		diags[from]+=(y+I*b/2.0);
		diags[to]+=(y+I*b/2.0);
	}
		
	//add diogonal entries to ybus.
	for(i=0; i<num_buses; i++) cs_ci_entry(ybus, i, i, diags[i]);
		
	//compress ybus
	ybus_comp=cs_ci_compress(ybus);	
	
	//check that memory allocation was okay
	if(!ybus_comp){cs_ci_spfree(ybus); return 1;}
		
	//free the old ybus and sum duplicates in the compressed matrix (i.e., parallel branches)
	cs_ci_spfree(ybus);
	cs_ci_dupl(ybus_comp);
	
	//sort the columns of ybus using the transpose-transpose trick
	ybus_comp_t = cs_ci_transpose(ybus_comp, 1);
	if(!ybus_comp_t){free(ybus_comp); return 1;}
	free(ybus_comp);
	ybus_comp = cs_ci_transpose(ybus_comp_t, 1);
	if(!ybus_comp){free(ybus_comp_t); return 1;}
	free(ybus_comp_t);
	
	//assign the ps ybus pointer to the compressed, summed ybus matrix	
	ps->ybus = ybus_comp;
		
	//free the diagonal workspace and return
	free(diags);
	return 0;
}
Beispiel #2
0
/* free workspace for demo3 */
static int done3 (int ok, cs_cis *S, cs_cin *N, cs_complex_t *y, cs_ci *W, cs_ci *E, int *p)
{
    cs_ci_sfree (S) ;
    cs_ci_nfree (N) ;
    cs_ci_free (y) ;
    cs_ci_spfree (W) ;
    cs_ci_spfree (E) ;
    cs_ci_free (p) ;
    return (ok) ;
}
Beispiel #3
0
/* free a problem */
problem *free_problem (problem *Prob)
{
    if (!Prob) return (NULL) ;
    cs_ci_spfree (Prob->A) ;
    if (Prob->sym) cs_ci_spfree (Prob->C) ;
    cs_ci_free (Prob->b) ;
    cs_ci_free (Prob->x) ;
    cs_ci_free (Prob->resid) ;
    return (cs_ci_free (Prob)) ;
}
void freeAllocationsAC(void) {
      
        if (circuit_simulation.matrix_sparsity == SPARSE)
	{
	      if (circuit_simulation.method == DIRECT)
	      {  
		    cs_ci_sfree( Scomplex );
		    cs_ci_nfree( Ncomplex );
	      }
	      else
	      {
		    cs_ci_spfree( G2complex );
	      }
	}
	else
	{
	    free( matrix_Gcomplex );

	    if (circuit_simulation.method == DIRECT && circuit_simulation.matrix_type == NONSPD)
	    {
		  free( transposition );
	    }
			  
        }
        
        if (circuit_simulation.method == ITERATIVE)
	{
		free( inv_preconditioner_complex );
	}
}
Beispiel #5
0
/* read a problem from a file */
problem *get_problem (FILE *f, double tol)
{
    cs_ci *T, *A, *C ;
    int sym, m, n, mn, nz1, nz2 ;
    problem *Prob ;
    Prob = cs_ci_calloc (1, sizeof (problem)) ;
    if (!Prob) return (NULL) ;
    T = cs_ci_load (f) ;                   /* load triplet matrix T from a file */
    Prob->A = A = cs_ci_compress (T) ;     /* A = compressed-column form of T */
    cs_ci_spfree (T) ;                     /* clear T */
    if (!cs_ci_dupl (A)) return (free_problem (Prob)) ; /* sum up duplicates */
    Prob->sym = sym = is_sym (A) ;      /* determine if A is symmetric */
    m = A->m ; n = A->n ;
    mn = CS_MAX (m,n) ;
    nz1 = A->p [n] ;
    cs_ci_dropzeros (A) ;                  /* drop zero entries */
    nz2 = A->p [n] ;
    if (tol > 0) cs_ci_droptol (A, tol) ;  /* drop tiny entries (just to test) */
    Prob->C = C = sym ? make_sym (A) : A ;  /* C = A + triu(A,1)', or C=A */
    if (!C) return (free_problem (Prob)) ;
    printf ("\n--- Matrix: %d-by-%d, nnz: %d (sym: %d: nnz %d), norm: %8.2e\n",
            m, n, A->p [n], sym, sym ? C->p [n] : 0, cs_ci_norm (C)) ;
    if (nz1 != nz2) printf ("zero entries dropped: %d\n", nz1 - nz2) ;
    if (nz2 != A->p [n]) printf ("tiny entries dropped: %d\n", nz2 - A->p [n]) ;
    Prob->b = cs_ci_malloc (mn, sizeof (cs_complex_t)) ;
    Prob->x = cs_ci_malloc (mn, sizeof (cs_complex_t)) ;
    Prob->resid = cs_ci_malloc (mn, sizeof (cs_complex_t)) ;
    return ((!Prob->b || !Prob->x || !Prob->resid) ? free_problem (Prob) : Prob) ;
}
Beispiel #6
0
/* C = A + triu(A,1)' */
static cs_ci *make_sym (cs_ci *A)
{
    cs_ci *AT, *C ;
    AT = cs_ci_transpose (A, 1) ;          /* AT = A' */
    cs_ci_fkeep (AT, &dropdiag, NULL) ;    /* drop diagonal entries from AT */
    C = cs_ci_add (A, AT, 1, 1) ;          /* C = A+AT */
    cs_ci_spfree (AT) ;
    return (C) ;
}
Beispiel #7
0
/*
 * Free memory allocated for power system data.
 */
int FreePS(PS *ps){
	if((*ps)->buses){free((*ps)->buses); (*ps)->buses = NULL;}
	if((*ps)->branches){free((*ps)->branches); (*ps)->branches = NULL;}
	if((*ps)->gens){free((*ps)->gens); (*ps)->gens = NULL;}
	if((*ps)->shunts){free((*ps)->shunts);(*ps)->shunts = NULL;}
	if((*ps)->machines){free((*ps)->machines);(*ps)->machines = NULL;}
	if((*ps)->src_buses){free((*ps)->src_buses); (*ps)->src_buses=NULL;}
	if((*ps)->ybus) cs_ci_spfree((*ps)->ybus);
	*ps = NULL;
	return 0;
};
Beispiel #8
0
void CholeskyDecompositionComplex(long int run)
{
	int k, i, j;
	unsigned int dimension;
	double sum, temp;
	double complex sum2;
#if DEBUG
	int l;
	double complex temp_val;
#endif

	dimension = circuit_simulation.number_of_nodes + circuit_simulation.group2_elements;

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		if(run == 0) {
	             printf( "\n\nCholesky Decomposition...\n\n" );
		}
		Scomplex = cs_ci_schol( 1, G2complex );
		Ncomplex = cs_ci_chol( G2complex, Scomplex );
		cs_ci_spfree( G2complex );

		if (Ncomplex == NULL)
		{
			printf( "Error, the matrix must be hermitian & positive definite.\n\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}
	}
	else
	{
	        if(run == 0) {
		    printf( "\n\nCholesky Decomposition...\n\n" );
                }

		for (k = 0; k < dimension; k++)
		{
			for (sum = 0, j = 0; j < k; j++)
			{
			      if (matrix_Gcomplex[k * dimension + j] != conj(matrix_Gcomplex[j * dimension + k]))
			      {
					printf( "Error, the matrix must be hermitian & positive definite.\n\n" );
					printf( "Terminating.\n" );
					exit( -1 );
			      }
			      
			      sum += creal(conj(matrix_Gcomplex[k * dimension + j]) * matrix_Gcomplex[k * dimension + j]);		
			}
			
			if(cimag(matrix_Gcomplex[k * dimension + k]) != 0) {
			      printf( "Error, the matrix must be hermitian & positive definite.\n\n" );
			      printf( "Terminating.\n" );
			      exit( -1 );
			}

			if ((temp = creal(matrix_Gcomplex[k * dimension + k]) - sum) < 0)
			{
				printf( "Error, the matrix must be hermitian & positive definite.\n\n" );
				printf( "Terminating.\n" );
				exit( -1 );
			}
			matrix_Gcomplex[k * dimension + k] = sqrt( temp );

			for (i = k + 1; i < dimension; i++)
			{
				for (sum2 = 0, j = 0; j < k; j++)
				{
					sum2 += conj(matrix_Gcomplex[i * dimension + j]) * matrix_Gcomplex[k * dimension + j];
				}
				matrix_Gcomplex[k * dimension + i] = matrix_Gcomplex[i * dimension + k] = (matrix_Gcomplex[k * dimension + i] - sum2) / matrix_Gcomplex[k * dimension + k];
			}
		}
	}
	
	#if DEBUG
		printf("\nCholesky Decomposition\n~~~~~~~~~~~~~~~~~~~~~~~\n\n");
		printf("\nDecomposed Matrix:\n\n");
		for(k = 0; k < dimension; k++)
		{
			for(l = 0; l < dimension; l++)
			{
				if(l == k)
				{
					printf("  \\\\");
				}
				
				if (circuit_simulation.matrix_sparsity == SPARSE)
				{
				      if(l <= k)
				      {
					    temp_val = getElementAtComplex(Ncomplex -> L, k, l);
					    printf("(%7.3lf %7.3lfi) ", creal(temp_val), cimag(temp_val));
				      }
				      else
				      {
					    temp_val = getElementAtComplex(Ncomplex -> L, l, k);
					    printf("(%7.3lf %7.3lfi) ", creal(temp_val), cimag(temp_val));
				      }
				}
				else {
				     printf("(%7.3lf %7.3lfi) ", creal(matrix_Gcomplex[k * dimension + l]), cimag(matrix_Gcomplex[k * dimension + l]));
				}
				
				if(l == k)
				{
					printf("  \\\\");
				}

			}
			printf("\n\n");
		}

		printf("\n\n");
#endif

}
Beispiel #9
0
void LUDecompositionComplex(long int run)
{
	int k, i, m, j;
	unsigned int dimension;
#if DEBUG
	int l;
	double complex temp_val;
#endif

	dimension = circuit_simulation.number_of_nodes + circuit_simulation.group2_elements;

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		if(run == 0) {
	            printf( "\n\nLU Decomposition...\n\n" );
		}
		Scomplex = cs_ci_sqr( 2, G2complex, 0 );
		Ncomplex = cs_ci_lu( G2complex, Scomplex, 1 );
		cs_ci_spfree( G2complex );

		if (Ncomplex == NULL)
		{
			printf( "Error, the matrix cannot be inverted.\n\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}
	}
	else
	{
		transposition = ( int * ) malloc( dimension * sizeof(int) );

		if (transposition == NULL)
		{
			printf( "Could not allocate matrices.\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}

		for (i = 0; i < dimension; i++)
		{
			transposition[i] = i;
		}

		if(run == 0) {
		      printf( "\n\nLU Decomposition...\n\n" );
		}

		for (k = 0; k < dimension - 1; k++)
		{
			for (m = i = k; i < dimension; i++)
			{
				if (cabs( matrix_Gcomplex[i * dimension + k] ) > cabs( matrix_Gcomplex[m * dimension + k] ))
				{
					m = i;
				}
			}

			interchangeComplex( m, k );

			if (cabs( matrix_Gcomplex[k * dimension + k] ) == 0)
			{
				printf( "Error, the matrix cannot be inverted.\n\n" );
				printf( "Terminating.\n" );
				exit( -1 );
			}

			for (i = k + 1; i < dimension; i++)
			{
				matrix_Gcomplex[i * dimension + k] /= matrix_Gcomplex[k * dimension + k];
				for (j = k + 1; j < dimension; j++)
				{
					matrix_Gcomplex[i * dimension + j] += -matrix_Gcomplex[i * dimension + k] * matrix_Gcomplex[k * dimension + j];
				}
			}
		}
	}
	
	
#if DEBUG
		printf("\nLU Decomposition\n~~~~~~~~~~~~~~~~~\n\n");
		printf("\nDecomposed Matrix:\n\n");
		for(k = 0; k < dimension; k++)
		{
			for(l = 0; l < dimension; l++)
			{
				if(l == k)
				{
					printf("  \\\\");
				}
				if (circuit_simulation.matrix_sparsity == SPARSE)
				{
				      if(l >= k)
				      {
					  temp_val = getElementAtComplex(Ncomplex -> U, k, l);	
					  printf("(%7.3lf %7.3lfi) ", creal(temp_val), cimag(temp_val));
				      }
				      else
				      {
					  temp_val = getElementAtComplex(Ncomplex -> L, k, l);
					  printf("(%7.3lf %7.3lfi) ", creal(temp_val), cimag(temp_val));
				      }
				}
				else {
				      printf("(%7.3lf %7.3lfi) ", creal(matrix_Gcomplex[k * dimension + l]), cimag(matrix_Gcomplex[k * dimension + l]));
				}
			}
			printf("\n\n");
		}

		printf("\n\n");

		printf("\nLine Transposition:\n");
		for(k = 0; k < dimension; k++)
		{
		      if (circuit_simulation.matrix_sparsity == SPARSE)
		      {
			    printf("line %d contains line %d\n", Ncomplex -> pinv[k], k);
		      }
		      else {
			    printf("line %d contains line %d\n", k, transposition[k]);
		      }
		}
		printf("\n\n");
#endif

}
Beispiel #10
0
/* Cholesky update/downdate */
int demo3 (problem *Prob)
{
    cs_ci *A, *C, *W = NULL, *WW, *WT, *E = NULL, *W2 ;
    int n, k, *Li, *Lp, *Wi, *Wp, p1, p2, *p = NULL, ok ;
    cs_complex_t *b, *x, *resid, *y = NULL, *Lx, *Wx, s ;
    double t, t1 ;
    cs_cis *S = NULL ;
    cs_cin *N = NULL ;
    if (!Prob || !Prob->sym || Prob->A->n == 0) return (0) ;
    A = Prob->A ; C = Prob->C ; b = Prob->b ; x = Prob->x ; resid = Prob->resid;
    n = A->n ;
    if (!Prob->sym || n == 0) return (1) ;
    rhs (x, b, n) ;                             /* compute right-hand side */
    printf ("\nchol then update/downdate ") ;
    print_order (1) ;
    y = cs_ci_malloc (n, sizeof (cs_complex_t)) ;
    t = tic () ;
    S = cs_ci_schol (1, C) ;                       /* symbolic Chol, amd(A+A') */
    printf ("\nsymbolic chol time %8.2f\n", toc (t)) ;
    t = tic () ;
    N = cs_ci_chol (C, S) ;                        /* numeric Cholesky */
    printf ("numeric  chol time %8.2f\n", toc (t)) ;
    if (!S || !N || !y) return (done3 (0, S, N, y, W, E, p)) ;
    t = tic () ;
    cs_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    printf ("solve    chol time %8.2f\n", toc (t)) ;
    printf ("original: ") ;
    print_resid (1, C, x, b, resid) ;           /* print residual */
    k = n/2 ;                                   /* construct W  */
    W = cs_ci_spalloc (n, 1, n, 1, 0) ;
    if (!W) return (done3 (0, S, N, y, W, E, p)) ;
    Lp = N->L->p ; Li = N->L->i ; Lx = N->L->x ;
    Wp = W->p ; Wi = W->i ; Wx = W->x ;
    Wp [0] = 0 ;
    p1 = Lp [k] ;
    Wp [1] = Lp [k+1] - p1 ;
    s = Lx [p1] ;
    srand (1) ;
    for ( ; p1 < Lp [k+1] ; p1++)
    {
        p2 = p1 - Lp [k] ;
        Wi [p2] = Li [p1] ;
        Wx [p2] = s * rand () / ((double) RAND_MAX) ;
    }
    t = tic () ;
    ok = cs_ci_updown (N->L, +1, W, S->parent) ;   /* update: L*L'+W*W' */
    t1 = toc (t) ;
    printf ("update:   time: %8.2f\n", t1) ;
    if (!ok) return (done3 (0, S, N, y, W, E, p)) ;
    t = tic () ;
    cs_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    p = cs_ci_pinv (S->pinv, n) ;
    W2 = cs_ci_permute (W, p, NULL, 1) ;           /* E = C + (P'W)*(P'W)' */
    WT = cs_ci_transpose (W2,1) ;
    WW = cs_ci_multiply (W2, WT) ;
    cs_ci_spfree (WT) ;
    cs_ci_spfree (W2) ;
    E = cs_ci_add (C, WW, 1, 1) ;
    cs_ci_spfree (WW) ;
    if (!E || !p) return (done3 (0, S, N, y, W, E, p)) ;
    printf ("update:   time: %8.2f (incl solve) ", t1+t) ;
    print_resid (1, E, x, b, resid) ;           /* print residual */
    cs_ci_nfree (N) ;                              /* clear N */
    t = tic () ;
    N = cs_ci_chol (E, S) ;                        /* numeric Cholesky */
    if (!N) return (done3 (0, S, N, y, W, E, p)) ;
    cs_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    printf ("rechol:   time: %8.2f (incl solve) ", t) ;
    print_resid (1, E, x, b, resid) ;           /* print residual */
    t = tic () ;
    ok = cs_ci_updown (N->L, -1, W, S->parent) ;   /* downdate: L*L'-W*W' */
    t1 = toc (t) ;
    if (!ok) return (done3 (0, S, N, y, W, E, p)) ;
    printf ("downdate: time: %8.2f\n", t1) ;
    t = tic () ;
    cs_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    printf ("downdate: time: %8.2f (incl solve) ", t1+t) ;
    print_resid (1, C, x, b, resid) ;           /* print residual */
    return (done3 (1, S, N, y, W, E, p)) ;
}