Exemplo n.º 1
0
void V_Unlock(QVector *V)
/* unlock the vector V */
{
    if (V != NULL) {
        V->LockLevel--;
        if (V->Instance == Tempor && V->LockLevel <= 0) {
            V_Destr(V); 
	    free(V);
	}
    }
}
Exemplo n.º 2
0
Vector *MGIter(int NoLevels, QMatrix *A, Vector *x, Vector *b,
	    Matrix *R, Matrix *P, int MaxIter, int Gamma,
            IterProcType SmoothProc, int Nu1, int Nu2, 
	    PrecondProcType PrecondProc, double Omega,
            IterProcType SolvProc, int NuC,
	    PrecondProcType PrecondProcC, double OmegaC)
/* multigrid method with residual termination control */
{
    int Iter;
    double bNorm;
    size_t Dim;
    Vector r;

    Dim = Q_GetDim(&A[NoLevels - 1]);
    V_Constr(&r, "r", Dim, Normal, True);

    if (LASResult() == LASOK) {
        bNorm = l2Norm_V(&b[NoLevels - 1]);

        Iter = 0;
        /* r = b - A x(i) at NoLevels - 1 */
        Asgn_VV(&r, Sub_VV(&b[NoLevels - 1], Mul_QV(&A[NoLevels - 1], &x[NoLevels - 1])));
        while (!RTCResult(Iter, l2Norm_V(&r), bNorm, MGIterId)
            && Iter < MaxIter) {
            Iter++;
            /* one multigrid step */
            MGStep(NoLevels, A, x, b, R, P, NoLevels - 1, Gamma,
		   SmoothProc, Nu1, Nu2, PrecondProc, Omega,
                   SolvProc, NuC, PrecondProcC, OmegaC);
            /* r = b - A x(i) at NoLevels - 1 */
            Asgn_VV(&r, Sub_VV(&b[NoLevels - 1], Mul_QV(&A[NoLevels - 1], &x[NoLevels - 1])));
        }
    }

    V_Destr(&r);

    return(&x[NoLevels - 1]);
}
Exemplo n.º 3
0
void Solver::ProccessStart(void) {

	#include "perem.cpp"
	#include "viraj.cpp"
#ifdef __TASK1__
	QMatrix A;
	Vector B, D;

	Q_Constr(&A, (char*)"A", 3 * total, False, Rowws, Normal, True);
	V_Constr(&B, (char*)"B", 3 * total, Normal, True);
	V_Constr(&D, (char*)"D", 3 * total, Normal, True);
	SetRTCAccuracy(1e-8);
#endif
#ifdef __TASK2__
	double *A = new double [3 * 9 * total * 3];
	int sizeA = 0;
	double *B = new double [3 * total];
	double *D = new double [3 * total];
#endif

#ifdef __TASK1__
		mm = 1;
#endif
#ifdef __TASK2__
		mm = 0;
#endif

 	for(int i = 0; i < total; i++) {
#ifdef __TASK1__
		V_SetCmp(&D, 3 * i + mm, G[i]);
		V_SetCmp(&D, 3 * i + 1 + mm, V1[i]);
		V_SetCmp(&D, 3 * i + 2 + mm, V2[i]);
#endif
#ifdef __TASK2__
		D[3 * i + mm] = G[i];
		D[3 * i + 1 + mm] = V1[i];
		D[3 * i + 2 + mm] = V2[i];
#endif
	}

	for (nn = 1; nn <= N;nn++) {
		tt = nn * tau;

		#include "mum.cpp"
//#ifdef __TASK1__
		mm = 1;
//#endif
#ifdef __TASK2__
//		mm = 0;
		sizeA = 0;
#endif
		for (m = 0; m < Dim; m++) {

		
			int n_, m_;
			int i00, i0m1, i0p1, i0pp1, i0mm1;
			i00 = m;
			Getmn(i00, &m_, &n_);
			GetN(&i0m1, m_, n_ - 1);
			GetN(&i0p1, m_, n_ + 1);
			GetN(&i0pp1, m_,n_ + 2);
			GetN(&i0mm1, m_,n_ - 2);

			M0L[m] = i0m1;
			M0R[m] = i0p1;
	
			xx = m_ * h1;
			yy = n_ * h2;

			switch (st[m]){
				#include "case0.cpp"
				#include "case1.cpp"
				#include "case2.cpp"
				#include "case3.cpp"
				#include "case4.cpp"
				#include "case5.cpp"
				#include "case6.cpp"
				#include "case7.cpp"
				#include "case8.cpp"
				#include "case9.cpp"
			}
		}


		//CGSIter(&A, &D, &B, 2000, NULL, 1.2);
#ifdef __TASK1__
		SetRTCAccuracy(1e-8);
		BiCGSTABIter(&A, &D, &B, 2000, NULL, 1.2);
#endif
#ifdef __TASK2__
		t2Solve(A, D, B, 3 * total, 2000);
#endif

#ifdef __TASK1__
	mm = 1;
#endif
#ifdef __TASK2__
	mm = 0;
#endif

		for (m = 0; m < Dim; m++) {
#ifdef __TASK1__
			G[m] = V_GetCmp(&D, 3 * m + mm);
			V1[m] = V_GetCmp(&D, 3 * m + 1 + mm);
			V2[m] = V_GetCmp(&D, 3 * m + 2 + mm);
#endif
#ifdef __TASK2__
			G[m] = D[3 * m + mm];
			V1[m] = D[3 * m + 1 + mm];
			V2[m] = D[3 * m + 2 + mm];
#endif
		}
#ifdef __TASK3__
		std::stringstream str;

		str << "_plot" << nn;
		FILE *f = fopen(str.str().c_str(), "w");
		for (m = 0; m < Dim; m++) {
			int n_, m_;
			Getmn(m, &m_, &n_);
			fprintf(f, "%lf %lf %lf %lf\n", m_ * h1, - n_ * h2, V1[m] / 10, - V2[m]);
		}
		fclose(f);

		str.str("");
		str << "_dense" << nn;
		FILE *fd = fopen(str.str().c_str(), "w");
		for (m = 0; m < Dim; m++) {
			int n_, m_;
			Getmn(m, &m_, &n_);
			fprintf(fd, "%lf %lf %d\n", m_ * h1, - n_ * h2, exp(G[m]) > 1);
		}
		fclose(fd);
#endif
	}	

#ifdef __TASK1__
	Q_Destr(&A);
	V_Destr(&B);
	V_Destr(&D);
#endif
#ifdef __TASK2__
	delete [] A;
	delete [] B;
	delete [] D;
#endif
}	
Exemplo n.º 4
0
Vector *BPXPCGIter(int NoLevels, QMatrix *A, Vector *z, Vector *r,
		   Matrix *R, Matrix *P, int MaxIter,
                   IterProcType SmoothProc, int Nu, 
		   PrecondProcType PrecondProc, double Omega,
                   IterProcType SmoothProcC, int NuC,
		   PrecondProcType PrecondProcC, double OmegaC)
/* BPX preconditioned CG method */
{
    int Iter;
    double Alpha, Beta, Rho, RhoOld = 0.0;
    double bNorm;
    size_t Dim;
    Vector x, p, q, b;

    Dim = Q_GetDim(&A[NoLevels - 1]);
    V_Constr(&x, "x", Dim, Normal, True);
    V_Constr(&p, "p", Dim, Normal, True);
    V_Constr(&q, "q", Dim, Normal, True);
    V_Constr(&b, "b", Dim, Normal, True);

    if (LASResult() == LASOK) {
        /* copy solution and right hand side stored in parameters z and r */
        Asgn_VV(&x, &z[NoLevels - 1]);
        Asgn_VV(&b, &r[NoLevels - 1]);
        
        bNorm = l2Norm_V(&b);
        
        Iter = 0;
        Asgn_VV(&r[NoLevels - 1], Sub_VV(&b, Mul_QV(&A[NoLevels - 1], &x)));
        while (!RTCResult(Iter, l2Norm_V(&r[NoLevels - 1]), bNorm, BPXPCGIterId)
            && Iter < MaxIter) {
            Iter++;
            /* BPX preconditioner */
            BPXPrecond(NoLevels, A, z, r, R, P, NoLevels - 1,
		SmoothProc, Nu, PrecondProc, Omega, SmoothProcC, NuC, PrecondProcC, OmegaC);
            Rho = Mul_VV(&r[NoLevels - 1], &z[NoLevels - 1]);
            if (Iter == 1) {
                Asgn_VV(&p, &z[NoLevels - 1]);
            } else {
                Beta = Rho / RhoOld;
                Asgn_VV(&p, Add_VV(&z[NoLevels - 1], Mul_SV(Beta, &p)));
            }
            Asgn_VV(&q, Mul_QV(&A[NoLevels - 1], &p));
            Alpha = Rho / Mul_VV(&p, &q);
            AddAsgn_VV(&x, Mul_SV(Alpha, &p));
            SubAsgn_VV(&r[NoLevels - 1], Mul_SV(Alpha, &q));
            RhoOld = Rho;
        }
        
	/* put solution and right hand side vectors back */
        Asgn_VV(&z[NoLevels - 1], &x);
        Asgn_VV(&r[NoLevels - 1], &b);
    }
    
    V_Destr(&x);
    V_Destr(&p);
    V_Destr(&q);
    V_Destr(&b);

    return(&z[NoLevels - 1]);
}
Exemplo n.º 5
0
Vector *Test4_QV(QMatrix *Q, Vector *V)
/* VRes = Q * V ... implementation using local variables and pointers,
                    descended counting of matrix elements */
{
    Vector *VRes;

    char *VResName;
    size_t Dim, Row, Clm, Len, ElCount;
    size_t *QLen;
    ElType **QEl, *PtrEl;
    Real Sum, Cmp;
    Real *VCmp, *VResCmp;

    if (LASResult() == LASOK) {
	if (Q->Dim == V->Dim) {
            Dim = Q->Dim;
	    VRes = (Vector *)malloc(sizeof(Vector));
	    VResName = (char *)malloc((strlen(Q_GetName(Q)) + strlen(V_GetName(V)) + 10)
		           * sizeof(char));
            if (VRes != NULL && VResName != NULL) {
	        sprintf(VResName, "(%s) * (%s)", Q_GetName(Q), V_GetName(V));
                V_Constr(VRes, VResName, Dim, Tempor, True);
		if (LASResult() == LASOK) {
                    /* initialisation of vector VRes */
		    if (Q->Symmetry || Q->ElOrder == Clmws)
                        V_SetAllCmp(VRes, 0.0);

                    /* analysis of multipliers of matrix Q and vector V
                       is not implemented yet */

                    /* multiplication of matrix elements by vector
                       components */
		    VCmp = V->Cmp;
		    VResCmp = VRes->Cmp;
                    QLen = Q->Len;
                    QEl = Q->El;
                    if (!Q->Symmetry) {
       		        if (Q->ElOrder == Rowws) {
		            for (Row = Dim; Row > 0; Row--) {
                                Len = QLen[Row];
                                PtrEl = QEl[Row] + Len - 1;
				Sum = 0.0;
			        for (ElCount = Len; ElCount > 0; ElCount--) {
				    Sum += (*PtrEl).Val * VCmp[(*PtrEl).Pos];
                                    PtrEl--;
			        }
				VResCmp[Row] = Sum;
  			    }
		        }
		        if (Q->ElOrder == Clmws) {
			    for (Clm = Dim; Clm > 0; Clm--) {
                                Len = QLen[Clm];
                                PtrEl = QEl[Clm] + Len - 1;
				Cmp = VCmp[Clm];
			        for (ElCount = Len; ElCount > 0; ElCount--) {
                                    VResCmp[(*PtrEl).Pos] += (*PtrEl).Val * Cmp;
                                    PtrEl--;;
			        }
			    }
		        }
                    } else {
                        /* multiplication by symmetric matrix is not
                           implemented yet */
                        V_SetAllCmp(VRes, 0.0);
                    }
		}
	    } else {
		LASError(LASMemAllocErr, "Mul_QV", Q_GetName(Q), V_GetName(V), NULL);
		if (VRes != NULL)
		    free(VRes);
		if (VResName != NULL)
		    free(VResName);
            }
	} else {
	    LASError(LASDimErr, "Mul_QV", Q_GetName(Q), V_GetName(V), NULL);
	    VRes = NULL;
	}
    } else {
        VRes = NULL;
    }

    if (Q != NULL) {
	if (Q->Instance == Tempor) {
	    Q_Destr(Q);
	    free(Q);
	}
    }
    if (V != NULL) {
	if (V->Instance == Tempor) {
	    V_Destr(V);
	    free(V);
	}
    }
    return(VRes);
}
Exemplo n.º 6
0
Vector *Test1_QV(QMatrix *Q, Vector *V)
/* VRes = Q * V ... very simple implementation */
{
    Vector *VRes;

    char *VResName;
    size_t Dim, Row, Clm, ElCount;
    ElType **QEl;

    if (LASResult() == LASOK) {
	if (Q->Dim == V->Dim) {
            Dim = Q->Dim;
            QEl = Q->El;
	    VRes = (Vector *)malloc(sizeof(Vector));
	    VResName = (char *)malloc((strlen(Q_GetName(Q)) + strlen(V_GetName(V)) + 10)
		           * sizeof(char));
            if (VRes != NULL && VResName != NULL) {
	        sprintf(VResName, "(%s) * (%s)", Q_GetName(Q), V_GetName(V));
                V_Constr(VRes, VResName, Dim, Tempor, True);
		if (LASResult() == LASOK) {
                    /* initialisation of vector VRes */
                    V_SetAllCmp(VRes, 0.0);

                    /* analysis of multipliers of matrix Q and vector V
                       is not implemented yet */

                    /* multiplication of matrix elements by vector
                       components */
                    if (!Q->Symmetry) {
       		        if (Q->ElOrder == Rowws) {
		            for (Row = 1; Row <= Dim; Row++) {
			        for (ElCount = 0; ElCount < Q->Len[Row]; ElCount++) {
				    Clm = QEl[Row][ElCount].Pos;
				    VRes->Cmp[Row] += QEl[Row][ElCount].Val * V->Cmp[Clm];
			        }
  			    }
		        }
		        if (Q->ElOrder == Clmws) {
			    for (Clm = 1; Clm <= Dim; Clm++) {
			        for (ElCount = 0; ElCount < Q->Len[Clm]; ElCount++) {
				    Row = QEl[Clm][ElCount].Pos;
				    VRes->Cmp[Row] += QEl[Clm][ElCount].Val * V->Cmp[Clm];
			        }
			    }
		        }
                    } else {
                        /* multiplication by symmetric matrix is not
                           implemented yet */
                        V_SetAllCmp(VRes, 0.0);
                    }
		}
	    } else {
		LASError(LASMemAllocErr, "Mul_QV", Q_GetName(Q), V_GetName(V), NULL);
		if (VRes != NULL)
		    free(VRes);
		if (VResName != NULL)
		    free(VResName);
            }
	} else {
	    LASError(LASDimErr, "Mul_QV", Q_GetName(Q), V_GetName(V), NULL);
	    VRes = NULL;
	}
    } else {
        VRes = NULL;
    }

    if (Q != NULL) {
	if (Q->Instance == Tempor) {
	    Q_Destr(Q);
	    free(Q);
	}
    }
    if (V != NULL) {
	if (V->Instance == Tempor) {
	    V_Destr(V);
	    free(V);
	}
    }
    return(VRes);
}
Exemplo n.º 7
0
static void EstimEigenvals(QMatrix *A, PrecondProcType PrecondProc, double OmegaPrecond)
/* estimates extremal eigenvalues of the matrix A by means of the Lanczos method */
{
    /*
     *  for details to the Lanczos algorithm see
     *
     *  G. H. Golub, Ch. F. van Loan:
     *  Matrix Computations;
     *  North Oxford Academic, Oxford, 1986
     *
     *  (for modification for preconditioned matrices compare with sec. 10.3) 
     *
     */
   
    double LambdaMin = 0.0, LambdaMax = 0.0;
    double LambdaMinOld, LambdaMaxOld;
    double GershBoundMin = 0.0, GershBoundMax = 0.0;
    double *Alpha, *Beta;
    size_t Dim, j;
    Boolean Found;
    Vector q, qOld, h, p;

    Q_Lock(A);
    
    Dim = Q_GetDim(A);
    V_Constr(&q, "q", Dim, Normal, True);
    V_Constr(&qOld, "qOld", Dim, Normal, True);
    V_Constr(&h, "h", Dim, Normal, True);
    if (PrecondProc != NULL)
        V_Constr(&p, "p", Dim, Normal, True);
   
    if (LASResult() == LASOK) {
        Alpha = (double *)malloc((Dim + 1) * sizeof(double));
        Beta = (double *)malloc((Dim + 1) * sizeof(double));
        if (Alpha != NULL && Beta != NULL) {
	    j = 0;
            
            V_SetAllCmp(&qOld, 0.0);
            V_SetRndCmp(&q);
	    if (Q_KerDefined(A))
	        OrthoRightKer_VQ(&q, A);
            if (Q_GetSymmetry(A) && PrecondProc != NULL) {
	        (*PrecondProc)(A, &p, &q, OmegaPrecond);
                MulAsgn_VS(&q, 1.0 / sqrt(Mul_VV(&q, &p)));
	    } else {
                MulAsgn_VS(&q, 1.0 / l2Norm_V(&q));
	    }
            
            Beta[0] = 1.0;
            do {
	        j++;
                if (Q_GetSymmetry(A) && PrecondProc != NULL) {
		    /* p = M^(-1) q */
		    (*PrecondProc)(A, &p, &q, OmegaPrecond);
		    /* h = A p */
                    Asgn_VV(&h, Mul_QV(A, &p));
	            if (Q_KerDefined(A))
	                OrthoRightKer_VQ(&h, A);
		    /* Alpha = p . h */
                    Alpha[j] = Mul_VV(&p, &h);
		    /* r = h - Alpha q - Beta qOld */
                    SubAsgn_VV(&h, Add_VV(Mul_SV(Alpha[j], &q), Mul_SV(Beta[j-1], &qOld)));
                    /* z = M^(-1) r */
		    (*PrecondProc)(A, &p, &h, OmegaPrecond);
		    /* Beta = sqrt(r . z) */
                    Beta[j] = sqrt(Mul_VV(&h, &p));
                    Asgn_VV(&qOld, &q);
		    /* q = r / Beta */
                    Asgn_VV(&q, Mul_SV(1.0 / Beta[j], &h));
		} else {
		    /* h = A p */
  		    if (Q_GetSymmetry(A)) {
                        Asgn_VV(&h, Mul_QV(A, &q));
		    } else {
                        if (PrecondProc != NULL) {
			    (*PrecondProc)(A, &h, Mul_QV(A, &q), OmegaPrecond);
			    (*PrecondProc)(Transp_Q(A), &h, &h, OmegaPrecond);
                            Asgn_VV(&h, Mul_QV(Transp_Q(A), &h));
                        } else {
                            Asgn_VV(&h, Mul_QV(Transp_Q(A), Mul_QV(A, &q)));
                        }
                    }
	            if (Q_KerDefined(A))
	                OrthoRightKer_VQ(&h, A); 
		    /* Alpha = q . h */
                    Alpha[j] = Mul_VV(&q, &h);
		    /* r = h - Alpha q - Beta qOld */
                    SubAsgn_VV(&h, Add_VV(Mul_SV(Alpha[j], &q), Mul_SV(Beta[j-1], &qOld)));
                    /* Beta = || r || */
		    Beta[j] = l2Norm_V(&h);
                    Asgn_VV(&qOld, &q);
		    /* q = r / Beta */
                    Asgn_VV(&q, Mul_SV(1.0 / Beta[j], &h));
		}
		
		LambdaMaxOld = LambdaMax;
                LambdaMinOld = LambdaMin;
		
                /* determination of extremal eigenvalues of the tridiagonal matrix
                   (Beta[i-1] Alpha[i] Beta[i]) (where 1 <= i <= j) 
		   by means of the method of bisection; bounds for eigenvalues
		   are determined after Gershgorin circle theorem */
                if (j == 1) {
		    GershBoundMin = Alpha[1] - fabs(Beta[1]);
	  	    GershBoundMax = Alpha[1] + fabs(Beta[1]);
		    
                    LambdaMin = Alpha[1];
                    LambdaMax = Alpha[1];
		} else {
		    GershBoundMin = min(Alpha[j] - fabs(Beta[j]) - fabs(Beta[j - 1]),
					GershBoundMin);
		    GershBoundMax = max(Alpha[j] + fabs(Beta[j]) + fabs(Beta[j - 1]),
				        GershBoundMax);

                    SearchEigenval(j, Alpha, Beta, 1, GershBoundMin, LambdaMin,
		        &Found, &LambdaMin);
		    if (!Found)
                        SearchEigenval(j, Alpha, Beta, 1, GershBoundMin, GershBoundMax,
		            &Found, &LambdaMin);
		    
	            SearchEigenval(j, Alpha, Beta, j, LambdaMax, GershBoundMax,
		        &Found, &LambdaMax);
		    if (!Found)
                        SearchEigenval(j, Alpha, Beta, j, GershBoundMin, GershBoundMax,
		            &Found, &LambdaMax);
                }
            } while (!IsZero(Beta[j]) && j < Dim
		&& (fabs(LambdaMin - LambdaMinOld) > EigenvalEps * LambdaMin
                || fabs(LambdaMax - LambdaMaxOld) > EigenvalEps * LambdaMax)
                && LASResult() == LASOK);
                
	    if (Q_GetSymmetry(A)) {
	        LambdaMin = (1.0 - j * EigenvalEps) * LambdaMin;
	    } else {
	        LambdaMin = (1.0 - sqrt(j) * EigenvalEps) * sqrt(LambdaMin);
            }
            if (Alpha != NULL)
                free(Alpha);
            if (Beta != NULL)
                free(Beta);
        } else {
            LASError(LASMemAllocErr, "EstimEigenvals", Q_GetName(A), NULL, NULL);
	}

    }
    
    V_Destr(&q);
    V_Destr(&qOld);
    V_Destr(&h);
    if (PrecondProc != NULL)
        V_Destr(&p);
    
    if (LASResult() == LASOK) {
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->MinEigenval = LambdaMin;
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->MaxEigenval = LambdaMax;
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->PrecondProcUsed = PrecondProc;
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->OmegaPrecondUsed = OmegaPrecond;
    } else {
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->MinEigenval = 1.0;
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->MaxEigenval = 1.0;
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->PrecondProcUsed = NULL;
        ((EigenvalInfoType *)*(Q_EigenvalInfo(A)))->OmegaPrecondUsed = 1.0;
    }

    Q_Unlock(A);
}