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(); }
///@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; }
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; }
//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; }
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; }
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) ); } } }
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; } } } }
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; }