예제 #1
0
int StokesFlow :: checkConsistency()
{
    int nelem;
    FMElement *sePtr;
    Domain *domain = this->giveDomain(1);
    nelem = domain->giveNumberOfElements();

    // check for proper element type
    for ( int i = 1; i <= nelem; i++ ) {
        sePtr = dynamic_cast< FMElement * >( domain->giveElement(i) );
        if ( sePtr == NULL ) {
            OOFEM_WARNING2("Element %d has no FMElement base", i);
            return false;
        }
    }

    return EngngModel :: checkConsistency();
}
예제 #2
0
///@todo Parallel mode of this.
NM_Status PetscSolver :: solve(SparseMtrx *A, FloatMatrix &B, FloatMatrix &X)
{
    if ( !A ) {
        _error("solve: Unknown Lhs");
    }
    if ( A->giveType() != SMT_PetscMtrx ) {
        _error("solve: PetscSparseMtrx Expected");
    }

    PetscSparseMtrx *Lhs = ( PetscSparseMtrx * ) A;

    Vec globRhsVec;
    Vec globSolVec;

    bool newLhs = true;
    int rows = B.giveNumberOfRows();
    int cols = B.giveNumberOfColumns();
    NM_Status s;
    X.resize(rows, cols);
    double *Xptr = X.givePointer();

    for (int i = 0; i < cols; ++i) {
        VecCreateSeqWithArray(PETSC_COMM_SELF, rows, B.givePointer() + rows*i, & globRhsVec);
        VecDuplicate(globRhsVec, & globSolVec);
        s = this->petsc_solve(Lhs, globRhsVec, globSolVec, newLhs);
        if ( !(s & NM_Success) ) {
            OOFEM_WARNING2("PetscSolver :: solve - No success at solving column %d",i+1);
            return s;
        }
        newLhs = false;
        double *ptr;
        VecGetArray(globSolVec, & ptr);
        for ( int j = 0; j < rows; ++j ) {
            Xptr[ j + rows*i ] = ptr [ j ];
        }
        VecRestoreArray(globSolVec, & ptr);
    }
    VecDestroy(globSolVec);
    VecDestroy(globRhsVec);
    return s;
}
예제 #3
0
double HydratingConcreteMat :: giveConcreteDensity(GaussPoint *gp)
{
    double concreteBulkDensity;

    if ( densityType == 0 ) { //get from input file
        concreteBulkDensity = IsotropicHeatTransferMaterial :: give('d', gp);
    } else if ( densityType == 1 ) { //calculate from 5-component model - not implemented
        OOFEM_ERROR2("Calculate from 5-component model, not implemented in densityType %d\n", densityType);
        concreteBulkDensity = 0.;
    } else {
        OOFEM_ERROR2("Unknown densityType %d\n", densityType);
        concreteBulkDensity = 0.;
    }

    //Parallel Voigt model, 7850 kg/m3 for steel
    concreteBulkDensity = concreteBulkDensity * ( 1. - this->reinforcementDegree ) + 7850. * this->reinforcementDegree;

    if ( concreteBulkDensity < 1000 || concreteBulkDensity > 4000 ) {
        OOFEM_WARNING2("Weird concrete density %f kg/m3\n", concreteBulkDensity);
    }

    return concreteBulkDensity;
}
예제 #4
0
//normally it returns J/kg/K of concrete
double HydratingConcreteMat :: giveConcreteCapacity(GaussPoint *gp)
{
    double capacityConcrete;

    if ( capacityType == 0 ) { //given from OOFEM input file
        capacityConcrete = IsotropicHeatTransferMaterial :: give('c', gp);
    } else if ( capacityType == 1 ) { ////calculate from 5-component model
        OOFEM_ERROR2("Calculate from 5-component model, not implemented in capacityType %d\n", capacityType);
        capacityConcrete = 0.;
    } else {
        OOFEM_ERROR2("Unknown capacityType %d\n", capacityType);
        capacityConcrete = 0.;
    }

    //Parallel Voigt model, 500 J/kg/K for steel
    capacityConcrete = capacityConcrete * ( 1. - this->reinforcementDegree ) + 500. * this->reinforcementDegree;

    if ( capacityConcrete < 500 || capacityConcrete > 2000 ) {
        OOFEM_WARNING2("Weird concrete heat capacity %f J/kg/K\n", capacityConcrete);
    }

    return capacityConcrete;
}
예제 #5
0
double HydratingConcreteMat :: giveIsotropicConductivity(GaussPoint *gp)
{
    HydratingConcreteMatStatus *ms = ( HydratingConcreteMatStatus * ) this->giveStatus(gp);
    double conduct;

    if ( conductivityType == 0 ) { //given from input file
        conduct = IsotropicHeatTransferMaterial :: give('k', gp);
    } else if ( conductivityType == 1 ) { //compute according to Ruiz, Schindler, Rasmussen. Kim, Chang: Concrete temperature modeling and strength prediction using maturity concepts in the FHWA HIPERPAV software, 7th international conference on concrete pavements, Orlando (FL), USA, 2001
        conduct = IsotropicHeatTransferMaterial :: give('k', gp) * ( 1.0 - 0.33 / 1.33 * ms->giveDoHActual() );
    } else {
        OOFEM_ERROR2("Unknown conductivityType %d\n", conductivityType);
        conduct = 0.;
    }

    //Parallel Voigt model, 20 W/m/K for steel
    conduct = conduct * ( 1. - this->reinforcementDegree ) + 20. * this->reinforcementDegree;

    if ( conduct < 0.3 || conduct > 5 ) {
        OOFEM_WARNING2("Weird concrete thermal conductivity %f W/m/K\n", conduct);
    }

    return conduct;
}
int
NodalAveragingRecoveryModel :: recoverValues(InternalStateType type, TimeStep *tStep)
{
    int ireg, nregions = this->giveNumberOfVirtualRegions();
    int ielem, nelem = domain->giveNumberOfElements();
    int inode, nnodes = domain->giveNumberOfDofManagers();
    int elemNodes;
    int regionValSize;
    int elementNode, node;
    int regionDofMans;
    int i, neq, eq;
    Element *element;
    NodalAveragingRecoveryModelInterface *interface;
    IntArray skipRegionMap(nregions), regionRecSize(nregions);
    IntArray regionNodalNumbers(nnodes);
    IntArray regionDofMansConnectivity;
    FloatArray lhs, val;


    if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) {
        return 1;
    }

#ifdef __PARALLEL_MODE
    bool parallel = this->domain->giveEngngModel()->isParallel();
    if (parallel)
        this->initCommMaps();
#endif

    // clear nodal table
    this->clear();

    // init region table indicating regions to skip
    this->initRegionMap(skipRegionMap, regionRecSize, type);

#ifdef __PARALLEL_MODE
    if (parallel) {
        // synchronize skipRegionMap over all cpus
        IntArray temp_skipRegionMap(skipRegionMap);
        MPI_Allreduce(temp_skipRegionMap.givePointer(), skipRegionMap.givePointer(), nregions, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
    }
#endif

    // loop over regions
    for ( ireg = 1; ireg <= nregions; ireg++ ) {
        // skip regions
        if ( skipRegionMap.at(ireg) ) {
            continue;
        }

        // loop over elements and determine local region node numbering and determine and check nodal values size
        if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, ireg) == 0 ) {
            break;
        }

        regionValSize = regionRecSize.at(ireg);
        neq = regionDofMans * regionValSize;
        lhs.resize(neq);
        lhs.zero();
        regionDofMansConnectivity.resize(regionDofMans);
        regionDofMansConnectivity.zero();

        // assemble element contributions
        for ( ielem = 1; ielem <= nelem; ielem++ ) {
            element = domain->giveElement(ielem);

#ifdef __PARALLEL_MODE
            if ( element->giveParallelMode() != Element_local ) {
                continue;
            }

#endif
            if ( this->giveElementVirtualRegionNumber(ielem) != ireg ) {
                continue;
            }

            // If an element doesn't implement the interface, it is ignored.
            if ( ( interface = ( NodalAveragingRecoveryModelInterface * )
                               element->giveInterface(NodalAveragingRecoveryModelInterfaceType) ) == NULL ) {
                //abort();
                continue;
            }

            elemNodes = element->giveNumberOfDofManagers();
            // ask element contributions
            for ( elementNode = 1; elementNode <= elemNodes; elementNode++ ) {
                node = element->giveDofManager(elementNode)->giveNumber();
                interface->NodalAveragingRecoveryMI_computeNodalValue(val, elementNode, type, tStep);
                // if the element cannot evaluate this variable, it is ignored
                if ( val.giveSize() == 0 ) {
                    continue;
                }
                eq = ( regionNodalNumbers.at(node) - 1 ) * regionValSize;
                for ( i = 1; i <= regionValSize; i++ ) {
                    lhs.at(eq + i) += val.at(i);
                }

                regionDofMansConnectivity.at( regionNodalNumbers.at(node) )++;
            }
        } // end assemble element contributions

#ifdef __PARALLEL_MODE
        if (parallel)
            this->exchangeDofManValues(ireg, lhs, regionDofMansConnectivity, regionNodalNumbers, regionValSize);
#endif

        // solve for recovered values of active region
        for ( inode = 1; inode <= nnodes; inode++ ) {
            if ( regionNodalNumbers.at(inode) ) {
                eq = ( regionNodalNumbers.at(inode) - 1 ) * regionValSize;
                for ( i = 1; i <= regionValSize; i++ ) {
                    if ( regionDofMansConnectivity.at( regionNodalNumbers.at(inode) ) > 0 ) {
                        lhs.at(eq + i) /= regionDofMansConnectivity.at( regionNodalNumbers.at(inode) );
                    } else {
                        OOFEM_WARNING2("NodalAveragingRecoveryModel::recoverValues: values of dofmanager %d undetermined", inode);
                        lhs.at(eq + i) = 0.0;
                    }
                }
            }
        }

        // update recovered values
        this->updateRegionRecoveredValues(ireg, regionNodalNumbers, regionValSize, lhs);
    } // end loop over regions

    this->valType = type;
    this->stateCounter = tStep->giveSolutionStateCounter();
    return 1;
}
예제 #7
0
void
POIExportModule :: exportPrimVarAs(UnknownType valID, FILE *stream, TimeStep *tStep)
{
    Domain *d = emodel->giveDomain(1);
    int j;
    FloatArray pv, coords(3);
    InternalStateValueType type = ISVT_UNDEFINED;

    if ( valID == DisplacementVector ) {
        type = ISVT_VECTOR;
    } else if ( valID == FluxVector ) {
        type = ISVT_SCALAR;
    } else {
        OOFEM_ERROR("POIExportModule::exportPrimVarAs: unsupported UnknownType");
    }

    // print header
    if ( type == ISVT_SCALAR ) {
        fprintf(stream, "SCALARS prim_scalar_%d\n", ( int ) valID);
    } else if ( type == ISVT_VECTOR ) {
        fprintf(stream, "VECTORS vector_%d float\n", ( int ) valID);
    } else {
        fprintf(stderr, "POIExportModule::exportPrimVarAs: unsupported variable type\n");
    }


    SpatialLocalizer *sl = d->giveSpatialLocalizer();
    // loop over POIs
    std::list< POI_dataType > :: iterator PoiIter;
    for ( PoiIter = POIList.begin(); PoiIter != POIList.end(); ++PoiIter ) {
        coords.at(1) = ( * PoiIter ).x;
        coords.at(2) = ( * PoiIter ).y;
        coords.at(3) = ( * PoiIter ).z;
        //region = (*PoiIter).region;

        Element *source = sl->giveElementContainingPoint(coords, NULL);
        if ( source ) {
            // ask interface
            EIPrimaryUnknownMapperInterface *interface =
                ( EIPrimaryUnknownMapperInterface * ) ( source->giveInterface(EIPrimaryUnknownMapperInterfaceType) );
            if ( interface ) {
                interface->EIPrimaryUnknownMI_computePrimaryUnknownVectorAt(VM_Total, tStep, coords, pv);
            } else {
                pv.resize(0);
                OOFEM_WARNING2( "POIExportModule::exportPrimVarAs: element %d with no EIPrimaryUnknownMapperInterface support",
                                source->giveNumber() );
            }

            fprintf(stream, "%10d ", ( * PoiIter ).id);
            if ( pv.giveSize() ) {
                for ( j = 1; j <= pv.giveSize(); j++ ) {
                    fprintf( stream, " %15e ", pv.at(j) );
                }
            }

            fprintf(stream, "\n");
        } else {
            OOFEM_ERROR4( "POIExportModule::exportPrimVarAs: no element containing POI(%e,%e,%e) found",
                          coords.at(1), coords.at(2), coords.at(3) );
        }
    }
}
예제 #8
0
void
VTKXMLExportModule :: getPrimaryVariable(FloatArray &answer, DofManager *dman, TimeStep *tStep, UnknownType type, int ireg)
{
    IntArray dofIDMask(3);
    int indx, size;
    DofIDItem id;
    const FloatArray *recoveredVal;

    // This code is not perfect. It should be rewritten to handle all cases more gracefully.

    EquationID eid = EID_MomentumBalance; // Shouldn't be necessary
    InternalStateType iState = IST_DisplacementVector; // Shouldn't be necessary

    dofIDMask.resize(0);
    if ( ( type == DisplacementVector ) || ( type == EigenVector ) || ( type == VelocityVector ) ) {
        dofIDMask.setValues(3, (int)Undef, (int) Undef, (int) Undef);
        for (int j = 1; j <= dman->giveNumberOfDofs(); j++ ) {
            id = dman->giveDof(j)->giveDofID();
            if ( ( id == V_u ) || ( id == D_u ) ) {
                dofIDMask.at(1) = id;
            } else if ( ( id == V_v ) || ( id == D_v ) ) {
                dofIDMask.at(2) = id;
            } else if ( ( id == V_w ) || ( id == D_w ) ) {
                dofIDMask.at(3) = id;
            }
        }
        answer.resize(3);
    } else if ( type == FluxVector ) {
        dofIDMask.followedBy(C_1);
        eid = EID_ConservationEquation;
        iState = IST_MassConcentration_1;
        answer.resize(1);
    } else if ( type == Temperature ) {
        dofIDMask.followedBy(T_f);
        eid = EID_ConservationEquation;
        iState = IST_Temperature;
        answer.resize(1);
    } else if ( type == PressureVector ) {
        dofIDMask.followedBy(P_f);
        eid = EID_ConservationEquation;
        iState = IST_Pressure;
        answer.resize(1);
    } else {
        OOFEM_ERROR2( "VTKXMLExportModule: unsupported unknownType %s", __UnknownTypeToString(type) );
    }

    size = dofIDMask.giveSize();
    answer.zero();

    for (int j = 1; j <= size; j++ ) {
        id = (DofIDItem)dofIDMask.at(j);
        if ( id == Undef ) {
            answer.at(j) = 0.0;
        } else if ( ( indx = dman->findDofWithDofId( id ) ) ) {
            // primary variable available directly in DOF-manager
            answer.at(j) = dman->giveDof(indx)->giveUnknown(eid, VM_Total, tStep);
        } else if ( iState != IST_Undefined ) {
            // primary variable not directly available
            // but equivalent InternalStateType provided
            // in this case use smoother to recover nodal value

            // This can't deal with ValueModeType, and would recover over and over for some vectorial quantities like velocity.
            this->givePrimVarSmoother()->recoverValues(iState, tStep); // recover values if not done before
            this->givePrimVarSmoother()->giveNodalVector(recoveredVal, dman->giveNumber(), ireg);
            // here we have a lack of information about how to convert recovered values to response
            // if the size is compatible we accept it, otherwise give a warning and zero value.
            if ( size == recoveredVal->giveSize() ) {
                answer.at(j) = recoveredVal->at(j);
            } else {
                OOFEM_WARNING2("VTKXMLExportModule :: getDofManPrimaryVariable: recovered variable size mismatch for %d", type);
                answer.at(j) = 0.0;
            }
        }
    }
}
예제 #9
0
NM_Status
NRSolver :: solve(SparseMtrx *k, FloatArray *R, FloatArray *R0,
                  FloatArray *X, FloatArray *dX, FloatArray *F,
                  const FloatArray &internalForcesEBENorm, double &l, referenceLoadInputModeType rlm,
                  int &nite, TimeStep *tNow)
//
// this function solve the problem of the unbalanced equilibrium
// using NR scheme
//
//
{
    // residual, iteration increment of solution, total external force
    FloatArray rhs, ddX, RT;
    double RRT;
    int neq = X->giveSize();
    NM_Status status;
    bool converged, errorOutOfRangeFlag;
#ifdef __PARALLEL_MODE
 #ifdef __PETSC_MODULE
    PetscContext *parallel_context  = engngModel->givePetscContext(this->domain->giveNumber());
 #endif
#endif

    if ( engngModel->giveProblemScale() == macroScale ) {
        OOFEM_LOG_INFO("NRSolver: Iteration");
        if ( rtolf.at(1) > 0.0 ) OOFEM_LOG_INFO(" ForceError");
        if ( rtold.at(1) > 0.0 ) OOFEM_LOG_INFO(" DisplError");
        OOFEM_LOG_INFO("\n----------------------------------------------------------------------------\n");
    }

    l = 1.0;

    status = NM_None;
    this->giveLinearSolver();

    // compute total load R = R+R0
    RT = * R;
    if ( R0 ) {
        RT.add(*R0);
    }

#ifdef __PARALLEL_MODE
    RRT = parallel_context->norm(RT);
    RRT *= RRT;
#else
    RRT = RT.computeSquaredNorm();
#endif

    ddX.resize(neq);
    ddX.zero();

    // Fetch the matrix before evaluating internal forces.
    // This is intentional, since its a simple way to drastically increase convergence for nonlinear problems.
    // (This old tangent is just used)

    engngModel->updateComponent(tNow, NonLinearLhs, domain);
    if ( this->prescribedDofsFlag ) {
        if ( !prescribedEqsInitFlag ) {
            this->initPrescribedEqs();
        }
        applyConstraintsToStiffness(k);
    }

    nite = 0;
    do {
        // Compute the residual
        engngModel->updateComponent(tNow, InternalRhs, domain);
        rhs.beDifferenceOf(RT, *F);

        if ( this->prescribedDofsFlag ) {
            this->applyConstraintsToLoadIncrement(nite, k, rhs, rlm, tNow);
        }

        // convergence check
        converged = this->checkConvergence(RT, * F, rhs, ddX, * X, RRT, internalForcesEBENorm, nite, errorOutOfRangeFlag, tNow);

        if ( errorOutOfRangeFlag ) {
            status = NM_NoSuccess;
            OOFEM_WARNING2("NRSolver:  Divergence reached after %d iterations", nite);
            break;
        } else if ( converged && ( nite >= minIterations ) ) {
            break;
        } else if ( nite >= nsmax ) {
            OOFEM_LOG_DEBUG("Maximum number of iterations reached\n");
            break;
        }

        if ( nite > 0 ) {
            if ( ( NR_Mode == nrsolverFullNRM ) || ( ( NR_Mode == nrsolverAccelNRM ) && ( nite % MANRMSteps == 0 ) ) ) {
                engngModel->updateComponent(tNow, NonLinearLhs, domain);
                applyConstraintsToStiffness(k);
            }
        }

        if ( ( nite == 0 ) && ( deltaL < 1.0 ) ) { // deltaL < 1 means no increment applied, only equilibrate current state
            rhs.zero();
            R->zero();
            ddX = rhs;
        } else {
            linSolver->solve(k, & rhs, & ddX);
        }

        //
        // update solution
        //
        if ( this->lsFlag && ( nite > 0 ) ) { // Why not nite == 0 ?
            // line search
            LineSearchNM :: LS_status status;
            double eta;
            this->giveLineSearchSolver()->solve(X, & ddX, F, R, R0, prescribedEqs, 1.0, eta, status, tNow);
        }
        X->add(ddX);
        dX->add(ddX);
        tNow->incrementStateCounter(); // update solution state counter

        nite++; // iteration increment
    } while ( true ); // end of iteration

    status |= NM_Success;
    solved = 1;

    // Modify Load vector to include "quasi reaction"
    if ( R0 ) {
        for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
            R->at( prescribedEqs.at(i) ) = F->at( prescribedEqs.at(i) ) - R0->at( prescribedEqs.at(i) ) - R->at( prescribedEqs.at(i) );
        }
    } else {
        for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
            R->at( prescribedEqs.at(i) ) = F->at( prescribedEqs.at(i) ) - R->at( prescribedEqs.at(i) );
        }
    }

    this->lastReactions.resize(numberOfPrescribedDofs);

#ifdef VERBOSE
    if (numberOfPrescribedDofs) {
        // print quasi reactions if direct displacement control used
        OOFEM_LOG_INFO("\n");
        OOFEM_LOG_INFO("NRSolver:     Quasi reaction table                                 \n");
        OOFEM_LOG_INFO("NRSolver:     Node            Dof             Displacement    Force\n");
        double reaction;
        for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
            reaction = R->at( prescribedEqs.at(i) );
            if ( R0 ) {
                reaction += R0->at( prescribedEqs.at(i) );
            }
            lastReactions.at(i) = reaction;
            OOFEM_LOG_INFO("NRSolver:     %-15d %-15d %-+15.5e %-+15.5e\n", prescribedDofs.at(2 * i - 1), prescribedDofs.at(2 * i),
                           X->at( prescribedEqs.at(i) ), reaction);
        }
        OOFEM_LOG_INFO("\n");
    }
#endif

    return status;
}