コード例 #1
0
ファイル: CompareCmd.cpp プロジェクト: geodynamics/cigma
void compare(CompareCmd *env, FE_Field *field_a, PointField *field_b)
{
    if (env->verbose)
    {
        cout << "Comparing FE_Field against PointField" << endl;
    }
    assert(env->quadrature != 0);

    QuadratureRule *qr = env->quadrature;
    Residuals *residuals = env->residuals;

    // dimensions
    int nel = qr->meshPart->nel;
    int nq = qr->points->n_points();
    int valdim = field_a->n_rank();

    assert((nel*nq) == field_b->points->n_points());
    assert(valdim == field_b->values->n_dim());

    // field values at quadrature points
    Points phi_a, phi_b;
    double *values_a = new double[nq * valdim];
    double *values_b = new double[nq * valdim];
    phi_a.set_data(values_a, nq, valdim);
    phi_b.set_data(values_b, nq, valdim);

    residuals->reset_accumulator();
    env->start_timer(nel, "elts");

    // main loop
    for (int e = 0; e < nel; e++)
    {
        qr->select_cell(e);
        for (int q = 0; q < nq; q++)
        {
            double *globalPoint = (*(qr->points))[q];
            bool ca = field_a->eval(globalPoint, &values_a[q*valdim]);
            //bool cb = field_b->eval(globalPoint, &values_b[q*valdim]);
            for (int i = 0; i < valdim; i++)
            {
                values_b[q*valdim + i] = field_b->values->data[q*valdim + i];
            }
        }
        double err2 = qr->L2(phi_a, phi_b);
        double vol = qr->meshPart->cell->volume();
        //residuals->update(e, sqrt(err2)/vol);
        //residuals->update(e, sqrt(err2));
        residuals->update(e, sqrt(err2), vol);
        env->update_timer(e);
    }
    env->end_timer();

    // clean up
    delete [] values_a;
    delete [] values_b;
}
コード例 #2
0
ファイル: CompareCmd.cpp プロジェクト: geodynamics/cigma
void compare(CompareCmd *env, FE_Field *field_a, FE_Field *field_b)
{
    if (env->verbose)
    {
        cout << "Comparing FE_Field against FE_Field" << endl;
    }
    assert(env->quadrature != 0);

    QuadratureRule *qr = env->quadrature;
    Residuals *residuals = env->residuals;

    // dimensions
    int nel = qr->meshPart->nel;
    int nq = qr->points->n_points();
    int valdim = field_a->n_rank();

    // field values at quadrature points
    Points phi_a, phi_b;
    double *values_a = new double[nq * valdim];
    double *values_b = new double[nq * valdim];
    phi_a.set_data(values_a, nq, valdim);
    phi_b.set_data(values_b, nq, valdim);

    field_a->fe->initialize_basis_tab();
    residuals->reset_accumulator();

    // main loop
    env->start_timer(nel,"elts");
    for (int e = 0; e < nel; e++)
    {
        qr->select_cell(e);
        field_a->tabulate_element(e, phi_a.data);
        bool cb = field_b->Field::eval(*(qr->points), phi_b);
        double err2 = qr->L2(phi_a, phi_b);
        double vol = qr->meshPart->cell->volume();
        //residuals->update(e, sqrt(err2)/vol);
        //residuals->update(e, sqrt(err2));
        residuals->update(e, sqrt(err2), vol);
        env->update_timer(e);
    }
    env->end_timer();

    // clean up
    delete [] values_a;
    delete [] values_b;
}
void CompositeIntegrator::integrate() {

    mResult = 0;

    mGrid.resetIteration();

    while (mGrid.hasNextInterval()) {
        
        const Interval& interval = mGrid.nextInterval();

        QuadratureRule* localIntegrator = mFactory->create(mFunction, 
                                                interval.xLow, interval.xHigh);

        localIntegrator->integrate();

        mResult += localIntegrator->getResult();
    }
}
コード例 #4
0
int main(int argc, char* argv[]) {

    double a = 0;
    double b = 2;

    if (argc != 3 && argc != 5) {
        printHelp(argv);
        return 1;
    }

    if (strlen(argv[1]) > 1) {
        printHelp(argv);
        return 2;
    } 
    char method = argv[1][0];

    int functionIndex = atoi(argv[2]);
    if (functionIndex == 0) {
        printHelp(argv);
        return 3;
    }

    if (argc == 5) {
        a = atof(argv[3]);
        b = atof(argv[4]);
        if (b <= a) {
            printHelp(argv);
            return 4;
        }
    }

    fptr func = chooseFunc(functionIndex);
    QuadratureRule* integrator = createMethod(method, func, a, b);

    printf("performing integration\n");
    integrator->integrate();
    printf("result of integrating function %d in interval [%5.3lf, %5.3lf] = %5.3lf\n",
            functionIndex, a, b, integrator->getResult());

    return 0;
}
コード例 #5
0
ファイル: quad_test.cpp プロジェクト: bsumirak/ugcore
void PrintQuadRule(const QuadratureRule<2>& q)
{
	cout << "QuadRule\n";
	cout << "--------\n";
	cout << "Order: " << q.order() << "\n";
	cout << "Size:  " << q.size() << "\n";
	for(size_t i = 0; i < q.size(); ++i)
		cout << "Weight "<<i<<": "<<q.weight(i) <<"\n";
	for(size_t i = 0; i < q.size(); ++i)
		cout << "Point  "<<i<<": "<<q.point(i) <<"\n";

}
コード例 #6
0
void
LevelSetBDQRAdapter<FESpaceType, VectorType>::
update (UInt elementID, UInt localFaceID)
{
    // They are ordered so that the "mapping" in
    // QuadratureBoundary is right.

    std::vector<UInt> myLID (3);

    if (localFaceID == 0)
    {
        myLID[0] = 0;
        myLID[1] = 1;
        myLID[2] = 2;
    }
    else if (localFaceID == 1)
    {
        myLID[0] = 0;
        myLID[1] = 1;
        myLID[2] = 3;
    }
    else if (localFaceID == 2)
    {
        myLID[0] = 3;
        myLID[1] = 1;
        myLID[2] = 2;
    }
    else
    {
        myLID[0] = 0;
        myLID[1] = 3;
        myLID[2] = 2;
    }

    // Compute the global IDs
    std::vector<UInt> myGID (3);

    for (UInt i (0); i < 3; ++i)
    {
        myGID[i] = M_lsFESpace->dof().localToGlobalMap (elementID, myLID[i]);
    }

    // Check the level set values
    std::vector<UInt> localPositive;
    std::vector<UInt> localNegative;
    std::vector<Real> localPositiveValue;
    std::vector<Real> localNegativeValue;

    for (UInt i (0); i < 3; ++i)
    {
        if (M_lsValue[myGID[i]] >= 0)
        {
            localPositive.push_back (i);
            localPositiveValue.push_back (M_lsValue[myGID[i]]);
        }
        else
        {
            localNegative.push_back (i);
            localNegativeValue.push_back (M_lsValue[myGID[i]]);
        }
    }

    // Check if the element is actually cut by the interface.
    if (localPositive.empty() || localNegative.empty() )
    {
        M_isAdaptedElement = false;
        *M_adaptedQrBd =  M_qrBd;
    }
    else
    {

        M_isAdaptedElement = true;

        std::vector<std::vector<Real> >refCoor (3, std::vector<Real> (2) );
        refCoor[0][0] = 0.0;
        refCoor[0][1] = 0.0;
        refCoor[1][0] = 1.0;
        refCoor[1][1] = 0.0;
        refCoor[2][0] = 0.0;
        refCoor[2][1] = 1.0;

        QuadratureRule qrRef ("none", TRIANGLE, 3, 0, 0);

        // Disinguish the two cases
        if (localPositive.size() == 1)
        {
            // Do nothing
        }
        else
        {
            // Exchange positive and negative values
            localPositive.swap (localNegative);
            localPositiveValue.swap (localNegativeValue);
        }


        // Two negative case
        Real lambda1 = -localPositiveValue[0] / (localNegativeValue[0] - localPositiveValue[0]);

        std::vector < Real > I1 (2);
        I1[0] = refCoor[localPositive[0]][0] + lambda1 * (refCoor[localNegative[0]][0] - refCoor[localPositive[0]][0]);
        I1[1] = refCoor[localPositive[0]][1] + lambda1 * (refCoor[localNegative[0]][1] - refCoor[localPositive[0]][1]);

        Real lambda2 = -localPositiveValue[0] / (localNegativeValue[1] - localPositiveValue[0]);

        std::vector < Real > I2 (2);
        I2[0] = refCoor[localPositive[0]][0] + lambda2 * (refCoor[localNegative[1]][0] - refCoor[localPositive[0]][0]);
        I2[1] = refCoor[localPositive[0]][1] + lambda2 * (refCoor[localNegative[1]][1] - refCoor[localPositive[0]][1]);

        // First triangle
        {
            std::vector<Real> P0 (2);
            P0[0] = refCoor[localPositive[0]][0];
            P0[1] = refCoor[localPositive[0]][1];

            std::vector<Real> v1 (2);
            v1[0] = I1[0] - refCoor[localPositive[0]][0];
            v1[1] = I1[1] - refCoor[localPositive[0]][1];

            std::vector<Real> v2 (2);
            v2[0] = I2[0] - refCoor[localPositive[0]][0];
            v2[1] = I2[1] - refCoor[localPositive[0]][1];

            Real wRel (std::abs (v1[0]*v2[1] - v1[1]*v2[0]) );

            for (UInt iq (0); iq < M_qrBd.qr (0).nbQuadPt(); ++iq)
            {
                Real x (P0[0] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[0] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[0]);
                Real y (P0[1] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[1] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[1]);

                qrRef.addPoint (QuadraturePoint (x, y, M_qrBd.qr (0).weight (iq) *wRel) );
            }
        }

        // Second triangle
        {
            std::vector<Real> P0 (2);
            P0[0] = refCoor[localNegative[0]][0];
            P0[1] = refCoor[localNegative[0]][1];

            std::vector<Real> v1 (2);
            v1[0] = I1[0] - refCoor[localNegative[0]][0];
            v1[1] = I1[1] - refCoor[localNegative[0]][1];

            std::vector<Real> v2 (2);
            v2[0] = I2[0] - refCoor[localNegative[0]][0];
            v2[1] = I2[1] - refCoor[localNegative[0]][1];

            Real wRel (std::abs (v1[0]*v2[1] - v1[1]*v2[0]) );

            for (UInt iq (0); iq < M_qrBd.qr (0).nbQuadPt(); ++iq)
            {
                Real x (P0[0] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[0] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[0]);
                Real y (P0[1] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[1] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[1]);

                qrRef.addPoint (QuadraturePoint (x, y, M_qrBd.qr (0).weight (iq) *wRel) );
            }
        }

        // Third triangle
        {
            std::vector<Real> P0 (2);
            P0[0] = refCoor[localNegative[0]][0];
            P0[1] = refCoor[localNegative[0]][1];

            std::vector<Real> v1 (2);
            v1[0] = I2[0] - refCoor[localNegative[0]][0];
            v1[1] = I2[1] - refCoor[localNegative[0]][1];

            std::vector<Real> v2 (2);
            v2[0] = refCoor[localNegative[1]][0] - refCoor[localNegative[0]][0];
            v2[1] = refCoor[localNegative[1]][1] - refCoor[localNegative[0]][1];

            Real wRel (std::abs (v1[0]*v2[1] - v1[1]*v2[0]) );

            for (UInt iq (0); iq < M_qrBd.qr (0).nbQuadPt(); ++iq)
            {
                Real x (P0[0] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[0] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[0]);
                Real y (P0[1] + M_qrBd.qr (0).quadPointCoor (iq, 0) *v1[1] + M_qrBd.qr (0).quadPointCoor (iq, 1) *v2[1]);

                qrRef.addPoint (QuadraturePoint (x, y, M_qrBd.qr (0).weight (iq) *wRel) );
            }
        }

        // Call the make tretra
        M_adaptedQrBd.reset (new QuadratureBoundary (buildTetraBDQR (qrRef) ) );
    }
}
void
WallTensionEstimatorCylindricalCoordinates<Mesh >::constructGlobalStressVector()
{

    //Creating the local stress tensors
    VectorElemental elVecSigmaX (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
    VectorElemental elVecSigmaY (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
    VectorElemental elVecSigmaZ (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    LifeChrono chrono;

    //Constructing the patch area vector for reconstruction purposes
    solutionVect_Type patchArea (* (this->M_displacement), Unique, Add);
    patchArea *= 0.0;

    super::constructPatchAreaVector ( patchArea );

    //Before assembling the reconstruction process is done
    solutionVect_Type patchAreaR (patchArea, Repeated);

    QuadratureRule fakeQuadratureRule;

    Real refElemArea (0); //area of reference element
    //compute the area of reference element
    for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++)
    {
        refElemArea += this->M_FESpace->qr().weight (iq);
    }

    Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() );

    //Setting the quadrature Points = DOFs of the element and weight = 1
    std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor();
    std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad);
    fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() );
    fakeQuadratureRule.setPoints (coords, weights);

    //Set the new quadrature rule
    this->M_FESpace->setQuadRule (fakeQuadratureRule);

    this->M_displayer->leaderPrint (" \n*********************************\n  ");
    this->M_displayer->leaderPrint ("   Performing the analysis recovering the Cauchy stresses..., ", this->M_dataMaterial->solidType() );
    this->M_displayer->leaderPrint (" \n*********************************\n  ");

    UInt totalDof = this->M_FESpace->dof().numTotalDof();
    VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    //Vectors for the deformation tensor
    std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) );
    //Copying the displacement field into a vector with repeated map for parallel computations
    solutionVect_Type dRep (* (this->M_displacement), Repeated);

    chrono.start();

    //Loop on each volume
    for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i )
    {
        this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );

        elVecSigmaX.zero();
        elVecSigmaY.zero();
        elVecSigmaZ.zero();

        this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();

        UInt eleID = this->M_FESpace->fe().currentLocalId();

        //Extracting the local displacement
        for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( iNode );

            for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
            {
                UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
                dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig];
            }
        }

        //Compute the element tensor F
        AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() );

        //Compute the local vector of the principal stresses
        for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( nDOF );

            vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0);

            for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof();
            }

            this->M_sigma->Scale (0.0);
            this->M_firstPiola->Scale (0.0);
            this->M_cofactorF->Scale (0.0);
            this->M_deformationCylindricalF->Scale (0.0);

            moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF);

            //Compute the rightCauchyC tensor
            AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );

            //Compute the first Piola-Kirchhoff tensor
            this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);

            //Compute the Cauchy tensor
            AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);

            //Assembling the local vectors for local tensions Component X
            for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                (elVecSigmaX) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 0);
            }

            //Assembling the local vectors for local tensions Component Y
            for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                (elVecSigmaY) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 1);
            }

            //Assembling the local vectors for local tensions Component Z
            for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                (elVecSigmaZ) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 2);
            }

        }

        super::reconstructElementaryVector ( elVecSigmaX, patchAreaR, *this->M_FESpace );
        super::reconstructElementaryVector ( elVecSigmaY, patchAreaR, *this->M_FESpace );
        super::reconstructElementaryVector ( elVecSigmaZ, patchAreaR, *this->M_FESpace );

        //Assembling the three elemental vector in the three global
        for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic )
        {
            assembleVector (*this->M_sigmaX, elVecSigmaX, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
            assembleVector (*this->M_sigmaY, elVecSigmaY, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
            assembleVector (*this->M_sigmaZ, elVecSigmaZ, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
        }
    }


    this->M_sigmaX->globalAssemble();
    this->M_sigmaY->globalAssemble();
    this->M_sigmaZ->globalAssemble();
}
void
WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryEigenvaluesCylindrical ( void )
{

    LifeChrono chrono;

    this->M_displayer->leaderPrint (" \n*********************************\n  ");
    this->M_displayer->leaderPrint ("   Performing the analysis recovering the tensions..., ", this->M_dataMaterial->solidType() );
    this->M_displayer->leaderPrint (" \n*********************************\n  ");

    solutionVect_Type patchArea (* (this->M_displacement), Unique, Add);
    patchArea *= 0.0;

    super::constructPatchAreaVector ( patchArea );

    //Before assembling the reconstruction process is done
    solutionVect_Type patchAreaR (patchArea, Repeated);

    QuadratureRule fakeQuadratureRule;

    Real refElemArea (0); //area of reference element
    //compute the area of reference element
    for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++)
    {
        refElemArea += this->M_FESpace->qr().weight (iq);
    }

    Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() );

    //Setting the quadrature Points = DOFs of the element and weight = 1
    std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor();
    std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad);
    fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() );
    fakeQuadratureRule.setPoints (coords, weights);

    //Set the new quadrature rule
    this->M_FESpace->setQuadRule (fakeQuadratureRule);

    UInt totalDof = this->M_FESpace->dof().numTotalDof();
    VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    //Vectors for the deformation tensor
    std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) );
    //Copying the displacement field into a vector with repeated map for parallel computations
    solutionVect_Type dRep (* (this->M_displacement), Repeated);

    VectorElemental elVecTens (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    chrono.start();

    //Loop on each volume
    for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i )
    {
        this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );
        elVecTens.zero();

        this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();

        UInt eleID = this->M_FESpace->fe().currentLocalId();

        //Extracting the local displacement
        for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( iNode );

            for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
            {
                UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
                dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig];
            }
        }

        //Compute the element tensor F
        AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() );

        //Compute the local vector of the principal stresses
        for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( nDOF );
            vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0);

            for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof();
            }

            this->M_sigma->Scale (0.0);
            this->M_firstPiola->Scale (0.0);
            this->M_cofactorF->Scale (0.0);
            M_deformationCylindricalF->Scale (0.0);

            moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF);

            //Compute the rightCauchyC tensor
            AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );

            //Compute the first Piola-Kirchhoff tensor
            this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);

            //Compute the Cauchy tensor
            AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);

            //Compute the eigenvalue
            AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);

            //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
            //Check on the imaginary part of eigen values given by the Lapack method
            Real sum (0);
            for ( int i = 0; i < this->M_eigenvaluesI.size(); i++ )
            {
                sum += std::abs (this->M_eigenvaluesI[i]);
            }
            ASSERT_PRE ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );

            std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );

            //Assembling the local vector
            for ( int coor = 0; coor < this->M_eigenvaluesR.size(); coor++ )
            {
                elVecTens[iloc + coor * this->M_FESpace->fe().nbFEDof()] = this->M_eigenvaluesR[coor];
            }
        }

        super::reconstructElementaryVector ( elVecTens, patchAreaR, *this->M_FESpace );

        //Assembling the local into global vector
        for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic )
        {
            assembleVector (* (this->M_globalEigenvalues), elVecTens, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
        }
    }

    this->M_globalEigenvalues->globalAssemble();

    chrono.stop();
    this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );
}
コード例 #9
0
double integrateD(const KernelD & F, const Element & e)
{
    double result = 0.0;

    // Get the quadrature rules for azimuthal and polar integrations
    namespace mpl = boost::mpl;
    typedef typename mpl::at<rules_map, mpl::int_<PhiPoints> >::type PhiPolicy;
    typedef typename mpl::at<rules_map, mpl::int_<ThetaPoints> >::type ThetaPolicy;
    QuadratureRule<PhiPolicy> phiRule;
    QuadratureRule<ThetaPolicy> thetaRule;
    int upper_phi = PhiPoints / 2; // Upper limit for loop on phi points
    int upper_theta = ThetaPoints / 2; // Upper limit for loop on theta points

    // Extract relevant data from Element
    int nVertices = e.nVertices();
    Eigen::Vector3d normal = e.normal();
    Sphere sph = e.sphere();
    Eigen::Matrix3Xd vertices = e.vertices();
    Eigen::Matrix3Xd arcs = e.arcs();

    // Calculation of the tangent and the bitangent (binormal) vectors
    // Tangent, Bitangent and Normal form a local reference frame:
    // T <-> x; B <-> y; N <-> z
    Eigen::Vector3d tangent, bitangent;
    tangent_and_bitangent(normal, tangent, bitangent);

    std::vector<double> theta(nVertices), phi(nVertices), phinumb(nVertices+1);
    std::vector<int> numb(nVertices+1);
    // Clean-up heap crap
    std::fill_n(theta.begin(),   nVertices,   0.0);
    std::fill_n(phi.begin(),     nVertices,   0.0);
    std::fill_n(numb.begin(),    nVertices+1, 0);
    std::fill_n(phinumb.begin(), nVertices+1, 0.0);
    // Populate arrays and redefine tangent and bitangent
    e.spherical_polygon(tangent, bitangent, theta, phi, phinumb, numb);

    // Actual integration occurs here
    for (int i = 0; i < nVertices; ++i) { // Loop on edges
        double phiLower = phinumb[i]; // Lower vertex of edge
        double phiUpper = phinumb[i+1]; // Upper vertex of edge
        double phiA = (phiUpper - phiLower) / 2.0;
        double phiB = (phiUpper + phiLower) / 2.0;
        double thetaLower = theta[numb[i]];
        double thetaUpper = theta[numb[i+1]];
        double thetaMax = 0.0;
        Eigen::Vector3d oc = (arcs.col(i) - sph.center) / sph.radius;
        double oc_norm = oc.norm();
        double oc_norm2 = std::pow(oc_norm, 2);
        for (int j = 0; j < upper_phi; ++j) { // Loop on Gaussian points: phi integration
            for (int k = 0; k <= 1; ++k) {
                double ph = (2*k - 1) * phiA * phiRule.abscissa(j) + phiB;
                double cos_phi = std::cos(ph);
                double sin_phi = std::sin(ph);
                if (oc_norm2 < 1.0e-07) { // This should check if oc_norm2 is zero
                    double cotg_thmax = (std::sin(ph-phiLower) / std::tan(thetaUpper) + std::sin(phiUpper-ph) / std::tan(
                                thetaLower)) / std::sin(phiUpper - phiLower);
                    thetaMax = std::atan(1.0 / cotg_thmax);
                } else {
                    Eigen::Vector3d scratch;
                    scratch << tangent.dot(oc), bitangent.dot(oc), normal.dot(oc);
                    double aa = std::pow(tangent.dot(oc)*cos_phi + bitangent.dot(oc)*sin_phi,
                            2) + std::pow(normal.dot(oc), 2);
                    double bb = -normal.dot(oc) * oc_norm2;
                    double cc = std::pow(oc_norm2,
                            2) - std::pow(tangent.dot(oc)*cos_phi + bitangent.dot(oc)*sin_phi, 2);
                    double ds = std::pow(bb, 2) - aa*cc;
                    if (ds < 0.0) ds = 0.0;
                    double cs = (-bb + std::sqrt(ds)) / aa;
                    if (cs > 1.0) cs = 1.0;
                    if (cs < -1.0) cs = 1.0;
                    thetaMax = std::acos(cs);
                }
                double thetaA = thetaMax / 2.0;
                double scratch = 0.0;
                if (!(thetaMax < 1.0e-08)) {
                    for (int l = 0; l < upper_theta; ++l) { // Loop on Gaussian points: theta integration
                        for (int m = 0; m <= 1; ++m) {
                            double th = (2*m - 1) * thetaA  * thetaRule.abscissa(l) + thetaA;
                            double cos_theta = std::cos(th);
                            double sin_theta = std::sin(th);
                            Eigen::Vector3d point;
                            point(0) = tangent(0) * sin_theta * cos_phi
                                + bitangent(0) * sin_theta * sin_phi
                                + normal(0) * (cos_theta - 1.0);
                            point(1) = tangent(1) * sin_theta * cos_phi
                                + bitangent(1) * sin_theta * sin_phi
                                + normal(1) * (cos_theta - 1.0);
                            point(2) = tangent(2) * sin_theta * cos_phi
                                + bitangent(2) * sin_theta * sin_phi
                                + normal(2) * (cos_theta - 1.0);
                            double value = F(e.normal(),
                                    Eigen::Vector3d::Zero(),
                                    point); // Evaluate integrand at Gaussian point
                            scratch += std::pow(sph.radius, 2) * value * sin_theta * thetaA * thetaRule.weight(l);
                        }
                    }
                    result += scratch * phiA * phiRule.weight(j);
                }
            }
        }
    }
    return result;
}
コード例 #10
0
ファイル: CompareCmd.cpp プロジェクト: geodynamics/cigma
void compare(CompareCmd *env, Field *field_a, Field *field_b)
{
    const bool debug = false;

    if (env->verbose)
    {
        cout << "Comparing Field against Field" << endl;
    }
    assert(env->quadrature != 0);

    QuadratureRule *qr = env->quadrature;
    Residuals *residuals = env->residuals;

    // dimensions
    int nel = qr->meshPart->nel;
    int nq = qr->points->n_points();
    int ndim = field_a->n_dim();
    int valdim = field_a->n_rank();

    // field values at quadrature points
    Points phi_a, phi_b;
    double *values_a = new double[nq * valdim];
    double *values_b = new double[nq * valdim];
    phi_a.set_data(values_a, nq, valdim);
    phi_b.set_data(values_b, nq, valdim);

    residuals->reset_accumulator();
    env->start_timer(nel, "elts");

    // main loop
    for (int e = 0; e < nel; e++)
    {
        qr->select_cell(e);
        for (int q = 0; q < nq; q++)
        {
            double *globalPoint = (*(qr->points))[q];
            field_a->eval(globalPoint, &values_a[q*valdim]);
            field_b->eval(globalPoint, &values_b[q*valdim]);
            if (debug)
            {
                int j;
                cerr << e << " " << q << "  ";
                for (j = 0; j < ndim; j++)
                {
                    cerr << globalPoint[j] << " ";
                }
                cerr << "\t";
                for (j = 0; j < valdim; j++)
                {
                    cerr << values_a[valdim*q + j] << " ";
                }
                cerr << "\t";
                for (j = 0; j < valdim; j++)
                {
                    cerr << values_b[valdim*q + j] << " ";
                }
                cerr << endl;
            }
        }
        double err2 = qr->L2(phi_a, phi_b);
        double vol = qr->meshPart->cell->volume();
        //residuals->update(e, sqrt(err2)/vol);
        //residuals->update(e, sqrt(err2));
        residuals->update(e, sqrt(err2), vol);
        env->update_timer(e);
    }
    env->end_timer();

    // clean up
    delete [] values_a;
    delete [] values_b;
}