void ErrorCheckingExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { #if 0 if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) { return; } #endif // Error checking rules are hardcoded to domain 1 always. Domain *domain = emodel->giveDomain(1); OOFEM_LOG_INFO("Checking rules...\n"); for ( auto &rule: this->errorCheckingRules ) { this->allPassed &= rule->check(domain, tStep); } if ( !tStep->isNotTheLastStep() ) { if ( !this->allPassed ) { OOFEM_ERROR("Rule not passed, exiting with error"); } } if ( this->writeChecks ) { this->writeCheck(domain, tStep); } }
void OutputManager :: doElementOutput(FILE *file, TimeStep *tStep) { int nelem = domain->giveNumberOfElements(); if ( !testTimeStepOutput(tStep) ) { return; } fprintf(file, "\n\nElement output:\n---------------\n"); if ( element_all_out_flag && element_except.empty() ) { for ( int i = 1; i <= nelem; i++ ) { #ifdef __PARALLEL_MODE // test for remote element in parallel mode if ( domain->giveElement(i)->giveParallelMode() == Element_remote ) { continue; } #endif domain->giveElement(i)->printOutputAt(file, tStep); } } else { for ( int i = 1; i <= nelem; i++ ) { if ( _testElementOutput(i) ) { domain->giveElement(i)->printOutputAt(file, tStep); } } } fprintf(file, "\n\n"); }
void OutputManager :: doDofManOutput(FILE *file, TimeStep *tStep) { int ndofman = domain->giveNumberOfDofManagers(); if ( !testTimeStepOutput(tStep) ) { return; } fprintf(file, "\n\nDofManager output:\n------------------\n"); if ( dofman_all_out_flag && dofman_except.empty() ) { for ( int i = 1; i <= ndofman; i++ ) { #ifdef __PARALLEL_MODE // test for null dof in parallel mode if ( domain->giveDofManager(i)->giveParallelMode() == DofManager_null ) { continue; } #endif domain->giveDofManager(i)->printOutputAt(file, tStep); } } else { for ( int i = 1; i <= ndofman; i++ ) { if ( _testDofManOutput(i) ) { domain->giveDofManager(i)->printOutputAt(file, tStep); } } } fprintf(file, "\n\n"); }
int OutputManager :: testElementOutput(int num, TimeStep *tStep) { if ( testTimeStepOutput(tStep) ) { if ( _testElementOutput(num) ) { return 1; } } return 0; }
void POIExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) { return; } FILE *stream = this->giveOutputStream(tStep); fprintf(stream, "# POI DataFile\n"); fprintf( stream, "Output for time %f\n", tStep->giveTargetTime() ); this->exportPrimaryVars(stream, tStep); this->exportIntVars(stream, tStep); fclose(stream); }
void OutputExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) { return; } FILE *file = this->giveOutputStream(); fprintf(file, "\n=============================================================="); fprintf(file, "\nOutput for time %.8e ", tStep->giveTargetTime() * emodel->giveVariableScale(VST_Time) ); fprintf(file, "\n==============================================================\n"); emodel->printOutputAt(file, tStep, nodeSets, elementSets); fprintf(file, "\nUser time consumed by solution step %d: %.3f [s]\n\n", tStep->giveNumber(), emodel->giveSolutionStepTime()); }
void MatlabExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) { return; } int nelem = this->elList.giveSize(); if ( nelem == 0 ) { // no list given, export all elements this->elList.enumerate(this->emodel->giveDomain(1)->giveNumberOfElements()); } FILE *FID; FID = giveOutputStream(tStep); Domain *domain = emodel->giveDomain(1); ndim=domain->giveNumberOfSpatialDimensions(); // Output header fprintf( FID, "%%%% OOFEM generated export file \n"); fprintf( FID, "%% Output for time %f\n", tStep->giveTargetTime() ); fprintf( FID, "function [mesh area data specials ReactionForces IntegrationPointFields]=%s\n\n", functionname.c_str() ); if ( exportMesh ) { doOutputMesh(tStep, FID); } else { fprintf(FID, "\tmesh=[];\n"); } if ( exportData ) { doOutputData(tStep, FID); } else { fprintf(FID, "\tdata=[];\n"); } if ( exportArea ) { computeArea(tStep); fprintf(FID, "\tarea.xmax=%f;\n", smax.at(0)); fprintf(FID, "\tarea.xmin=%f;\n", smin.at(0)); fprintf(FID, "\tarea.ymax=%f;\n", smax.at(1)); fprintf(FID, "\tarea.ymin=%f;\n", smin.at(1)); if ( ndim == 2 ) { fprintf(FID, "\tarea.area=%f;\n", Area); fprintf(FID, "\tvolume=[];\n"); } else { fprintf(FID, "\tarea.zmax=%f;\n", smax.at(2)); fprintf(FID, "\tarea.zmin=%f;\n", smin.at(2)); fprintf(FID, "\tarea.area=[];\n"); fprintf(FID, "\tarea.volume=%f;\n", Volume); for (size_t i=0; i<this->partName.size(); i++) { fprintf(FID, "\tarea.volume_%s=%f;\n", partName.at(i).c_str(), partVolume.at(i)); } } } else { fprintf(FID, "\tarea.area=[];\n"); fprintf(FID, "\tarea.volume=[];\n"); } if ( exportSpecials ) { if ( !exportArea ) { computeArea(tStep); } doOutputSpecials(tStep, FID); } else { fprintf(FID, "\tspecials=[];\n"); } // Reaction forces if ( exportReactionForces ) { doOutputReactionForces(tStep, FID); } else { fprintf(FID, "\tReactionForces=[];\n"); } // Internal variables in integration points if ( exportIntegrationPointFields ) { doOutputIntegrationPointFields(tStep, FID); } else { fprintf(FID, "\tIntegrationPointFields=[];\n"); } // Homogenized quantities if ( exportHomogenizeIST ) { doOutputHomogenizeDofIDs(tStep, FID); } fprintf(FID, "\nend\n"); fclose(FID); }
///////////////////////////////////////////////// // Help functions void GnuplotExportModule::outputReactionForces(TimeStep *tStep) { // Add sum of reaction forces to arrays // Compute sum of reaction forces for each BC number Domain *domain = emodel->giveDomain(1); StructuralEngngModel *seMod = dynamic_cast<StructuralEngngModel* >(emodel); if(seMod == NULL) { OOFEM_ERROR("failed to cast to StructuralEngngModel."); } IntArray ielemDofMask; FloatArray reactions; IntArray dofManMap, dofidMap, eqnMap; // test if solution step output is active if ( !testTimeStepOutput(tStep) ) { return; } // map contains corresponding dofmanager and dofs numbers corresponding to prescribed equations // sorted according to dofmanger number and as a minor crit. according to dof number // this is necessary for extractor, since the sorted output is expected seMod->buildReactionTable(dofManMap, dofidMap, eqnMap, tStep, 1); // compute reaction forces seMod->computeReaction(reactions, tStep, 1); // Find highest index of prescribed dofs int maxIndPresDof = 0; for ( int i = 1; i <= dofManMap.giveSize(); i++ ) { maxIndPresDof = std::max(maxIndPresDof, dofidMap.at(i)); } int numBC = domain->giveNumberOfBoundaryConditions(); while ( mReactionForceHistory.size() < size_t(numBC) ) { std::vector<FloatArray> emptyArray; mReactionForceHistory.push_back( emptyArray ); } maxIndPresDof = domain->giveNumberOfSpatialDimensions(); while ( mDispHist.size() < size_t(numBC) ) { std::vector<double> emptyArray; mDispHist.push_back( emptyArray ); } for(int bcInd = 0; bcInd < numBC; bcInd++) { FloatArray fR(maxIndPresDof), disp(numBC); fR.zero(); for ( int i = 1; i <= dofManMap.giveSize(); i++ ) { DofManager *dMan = domain->giveDofManager( dofManMap.at(i) ); Dof *dof = dMan->giveDofWithID( dofidMap.at(i) ); if ( dof->giveBcId() == bcInd+1 ) { fR.at( dofidMap.at(i) ) += reactions.at( eqnMap.at(i) ); // Slightly dirty BoundaryCondition *bc = dynamic_cast<BoundaryCondition*> (domain->giveBc(bcInd+1)); if ( bc != NULL ) { disp.at(bcInd+1) = bc->give(dof, VM_Total, tStep->giveTargetTime()); } ///@todo This function should be using the primaryfield instead of asking BCs directly. / Mikael } } mDispHist[bcInd].push_back(disp.at(bcInd+1)); mReactionForceHistory[bcInd].push_back(fR); // X FILE * pFileX; char fileNameX[100]; sprintf(fileNameX, "ReactionForceGnuplotBC%dX.dat", bcInd+1); pFileX = fopen ( fileNameX , "wb" ); fprintf(pFileX, "#u Fx\n"); for ( size_t j = 0; j < mDispHist[bcInd].size(); j++ ) { fprintf(pFileX, "%e %e\n", mDispHist[bcInd][j], mReactionForceHistory[bcInd][j].at(1) ); } fclose(pFileX); // Y FILE * pFileY; char fileNameY[100]; sprintf(fileNameY, "ReactionForceGnuplotBC%dY.dat", bcInd+1); pFileY = fopen ( fileNameY , "wb" ); fprintf(pFileY, "#u Fx\n"); for ( size_t j = 0; j < mDispHist[bcInd].size(); j++ ) { if( mReactionForceHistory[bcInd][j].giveSize() >= 2 ) { fprintf(pFileY, "%e %e\n", mDispHist[bcInd][j], mReactionForceHistory[bcInd][j].at(2) ); } } fclose(pFileY); } }
void GnuplotExportModule::doOutput(TimeStep *tStep, bool forcedOutput) { if (!(testTimeStepOutput(tStep) || forcedOutput)) { return; } // Export the sum of reaction forces for each Dirichlet BC if(mExportReactionForces) { outputReactionForces(tStep); } Domain *domain = emodel->giveDomain(1); // Export output from boundary conditions if(mExportBoundaryConditions) { int numBC = domain->giveNumberOfBoundaryConditions(); for(int i = 1; i <= numBC; i++) { PrescribedGradient *presGradBC = dynamic_cast<PrescribedGradient*>( domain->giveBc(i) ); if(presGradBC != NULL) { outputBoundaryCondition(*presGradBC, tStep); } PrescribedGradientBCNeumann *presGradBCNeumann = dynamic_cast<PrescribedGradientBCNeumann*>( domain->giveBc(i) ); if(presGradBCNeumann != NULL) { outputBoundaryCondition(*presGradBCNeumann, tStep); } PrescribedGradientBCWeak *presGradBCWeak = dynamic_cast<PrescribedGradientBCWeak*>( domain->giveBc(i) ); if(presGradBCWeak != NULL) { outputBoundaryCondition(*presGradBCWeak, tStep); } } } mTimeHist.push_back( tStep->giveTargetTime() ); if(mExportXFEM) { if(domain->hasXfemManager()) { XfemManager *xMan = domain->giveXfemManager(); int numEI = xMan->giveNumberOfEnrichmentItems(); std::vector< std::vector<FloatArray> > points; for(int i = 1; i <= numEI; i++) { EnrichmentItem *ei = xMan->giveEnrichmentItem(i); ei->callGnuplotExportModule(*this, tStep); GeometryBasedEI *geoEI = dynamic_cast<GeometryBasedEI*>(ei); if(geoEI != NULL) { std::vector<FloatArray> eiPoints; geoEI->giveSubPolygon(eiPoints, 0.0, 1.0); points.push_back(eiPoints); } } outputXFEMGeometry(points); } } if(mExportMesh) { outputMesh(*domain); } if(mMonitorNodeIndex != -1) { DofManager *dMan = domain->giveDofManager(mMonitorNodeIndex); outputNodeDisp(*dMan, tStep); } }
void VTKXMLExportModule :: doOutput(TimeStep *tStep) { if ( !testTimeStepOutput(tStep) ) { return; } #ifdef __VTK_MODULE vtkSmartPointer<vtkUnstructuredGrid> stream = vtkSmartPointer<vtkUnstructuredGrid>::New(); vtkSmartPointer<vtkPoints> nodes = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkIdList> elemNodeArray = vtkSmartPointer<vtkIdList>::New(); #else FILE *stream = this->giveOutputStream(tStep); struct tm *current; time_t now; time(&now); current = localtime(&now); fprintf(stream, "<!-- TimeStep %e Computed %d-%02d-%02d at %02d:%02d:%02d -->\n", tStep->giveIntrinsicTime(), current->tm_year+1900, current->tm_mon+1, current->tm_mday, current->tm_hour, current->tm_min, current->tm_sec); fprintf(stream, "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"); fprintf(stream, "<UnstructuredGrid>\n"); #endif Domain *d = emodel->giveDomain(1); Element *elem; FloatArray *coords; int nelem = d->giveNumberOfElements(); this->giveSmoother(); // make sure smoother is created // output nodes Region By Region int nregions = this->smoother->giveNumberOfVirtualRegions(); int regionDofMans, totalcells; IntArray mapG2L, mapL2G; /* loop over regions */ for ( int ireg = 1; ireg <= nregions; ireg++ ) { if ( ( ireg > 0 ) && ( this->regionsToSkip.contains(ireg) ) ) { continue; } // assemble local->global and global->local region map // and get number of single cells to process // the composite cells exported individually this->initRegionNodeNumbering(mapG2L, mapL2G, regionDofMans, totalcells, d, ireg); /* start default piece containing all single cell elements * the elements with composite geometry are assumed to be exported in individual pieces * after the default one */ #ifndef __PARALLEL_MODE if ( regionDofMans && totalcells ) { #else if ( 1 ) { #endif #ifdef __VTK_MODULE for ( int inode = 1; inode <= regionDofMans; inode++ ) { coords = d->giveNode(mapL2G.at(inode))->giveCoordinates(); int dims = coords->giveSize(); nodes->InsertNextPoint(coords->at(1), dims >= 2 ? coords->at(2) : 0.0, dims >= 3 ? coords->at(3) : 0.0); } stream->SetPoints(nodes); #else fprintf(stream, "<Piece NumberOfPoints=\"%d\" NumberOfCells=\"%d\">\n", regionDofMans, totalcells); // export nodes in region as vtk vertices fprintf(stream, "<Points>\n <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\"> "); for ( int inode = 1; inode <= regionDofMans; inode++ ) { coords = d->giveNode( mapL2G.at(inode) )->giveCoordinates(); for ( int i = 1; i <= coords->giveSize(); i++ ) { fprintf( stream, "%e ", coords->at(i) ); } for ( int i = coords->giveSize() + 1; i <= 3; i++ ) { fprintf(stream, "%e ", 0.0); } } fprintf(stream, "</DataArray>\n</Points>\n"); #endif // output all cells of the piece int nelemNodes; IntArray cellNodes; #ifdef __VTK_MODULE stream->Allocate(nelem); #else fprintf(stream, "<Cells>\n"); // output the connectivity data fprintf(stream, " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\"> "); #endif for ( int ielem = 1; ielem <= nelem; ielem++ ) { elem = d->giveElement(ielem); if ( ( ireg > 0 ) && ( this->smoother->giveElementVirtualRegionNumber(ielem) != ireg ) ) { continue; } if ( this->isElementComposite(elem) ) { continue; // composite cells exported individually } if ( !elem-> isActivated(tStep) ) { //skip inactivated elements continue; } #ifdef __PARALLEL_MODE if ( elem->giveParallelMode() != Element_local ) { continue; } #endif nelemNodes = elem->giveNumberOfNodes(); this->giveElementCell(cellNodes, elem, 0); #ifdef __VTK_MODULE elemNodeArray->Reset(); elemNodeArray->SetNumberOfIds(nelemNodes); #endif for ( int i = 1; i <= nelemNodes; i++ ) { #ifdef __VTK_MODULE elemNodeArray->SetId(i-1, mapG2L.at( cellNodes.at(i) ) - 1); #else fprintf(stream, "%d ", mapG2L.at( cellNodes.at(i) ) - 1); #endif } #ifdef __VTK_MODULE stream->InsertNextCell(this->giveCellType(elem), elemNodeArray); #else fprintf(stream, " "); #endif } #ifndef __VTK_MODULE int vtkCellType; fprintf(stream, "</DataArray>\n"); // output the offsets (index of individual element data in connectivity array) fprintf(stream, " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\"> "); int offset = 0; for ( int ielem = 1; ielem <= nelem; ielem++ ) { elem = d->giveElement(ielem); if ( ( ireg > 0 ) && ( this->smoother->giveElementVirtualRegionNumber(ielem) != ireg ) ) { continue; } #ifdef __PARALLEL_MODE if ( elem->giveParallelMode() != Element_local ) { continue; } #endif offset += elem->giveNumberOfNodes(); fprintf(stream, "%d ", offset); } fprintf(stream, "</DataArray>\n"); // output cell (element) types fprintf(stream, " <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\"> "); for ( int ielem = 1; ielem <= nelem; ielem++ ) { elem = d->giveElement(ielem); if ( ( ireg > 0 ) && ( this->smoother->giveElementVirtualRegionNumber(ielem) != ireg ) ) { continue; } if ( this->isElementComposite(elem) ) { continue; // composite cells exported individually } #ifdef __PARALLEL_MODE if ( elem->giveParallelMode() != Element_local ) { continue; } #endif vtkCellType = this->giveCellType(elem); fprintf(stream, "%d ", vtkCellType); } fprintf(stream, "</DataArray>\n"); fprintf(stream, "</Cells>\n"); #endif // export primary and internal variables #ifndef __VTK_MODULE this->exportPointDataHeader(stream, tStep); #endif this->exportPrimaryVars(stream, mapG2L, mapL2G, regionDofMans, ireg, tStep); this->exportIntVars(stream, mapG2L, mapL2G, regionDofMans, ireg, tStep); #ifndef __VTK_MODULE fprintf(stream, "</PointData>\n"); #endif //export cell data this->exportCellVars(stream, ireg, tStep); #ifndef __VTK_MODULE // end of piece record fprintf(stream, "</Piece>\n"); #endif } // end of default piece for simple geometry elements #if 1 // loop over region elements with multi-cell geometry for ( int ielem = 1; ielem <= nelem; ielem++ ) { elem = d->giveElement(ielem); if ( this->regionsToSkip.contains( this->smoother->giveElementVirtualRegionNumber(ielem) ) ) { continue; } #ifdef __PARALLEL_MODE if ( elem->giveParallelMode() != Element_local ) { continue; } #endif if ( this->isElementComposite(elem) ) { #ifndef __VTK_MODULE ///@todo Not sure how to deal with this. // multi cell (composite) elements should support vtkxmlexportmoduleinterface // and are exported as individual pieces (see VTKXMLExportModuleElementInterface) VTKXMLExportModuleElementInterface *interface = ( VTKXMLExportModuleElementInterface * ) elem->giveInterface(VTKXMLExportModuleElementInterfaceType); if ( interface ) { // passing this to access general piece related methods like exportPointDataHeader, etc. interface->_export(stream, this, primaryVarsToExport, internalVarsToExport, tStep); } #endif } } // end loop over multi-cell elements #endif } // end loop over regions std::string fname = giveOutputFileName(tStep); #ifdef __VTK_MODULE #if 0 // Doesn't as well as I would want it to, interface to VTK is to limited to control this. // * The PVTU-file is written by every process (seems to be impossible to avoid). // * Part files are renamed and time step and everything else is cut off => name collisions vtkSmartPointer<vtkXMLPUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New(); writer->SetTimeStep(tStep->giveNumber()-1); writer->SetNumberOfPieces( this->emodel->giveNumberOfProcesses() ); writer->SetStartPiece( this->emodel->giveRank() ); writer->SetEndPiece( this->emodel->giveRank() ); #else vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New(); #endif writer->SetFileName(fname.c_str()); writer->SetInput(stream); // Optional - set the mode. The default is binary. //writer->SetDataModeToBinary(); //writer->SetDataModeToAscii(); writer->Write(); #else // finish unstructured grid data and vtk file fprintf(stream, "</UnstructuredGrid>\n</VTKFile>"); fclose(stream); #endif // Writing the *.pvd-file. Only time step information for now. It's named "timestep" but is actually the total time. // First we check to see that there are more than 1 time steps, otherwise it is redundant; #ifdef __PARALLEL_MODE if ( emodel->isParallel() && emodel->giveRank() == 0 ) { ///@todo Should use probably use PVTU-files instead. It is starting to get messy. // For this to work, all processes must have an identical output file name. for (int i = 0; i < this->emodel->giveNumberOfProcesses(); ++i) { std::ostringstream pvdEntry; char fext[100]; if (this->emodel->giveNumberOfProcesses() > 1) { sprintf( fext, "_%03d.m%d.%d", i, this->number, tStep->giveNumber() ); } else { sprintf( fext, "m%d.%d", this->number, tStep->giveNumber() ); } pvdEntry << "<DataSet timestep=\"" << tStep->giveIntrinsicTime() << "\" group=\"\" part=\"" << i << "\" file=\"" << this->emodel->giveOutputBaseFileName() << fext << ".vtu\"/>"; this->pvdBuffer.push_back(pvdEntry.str()); } this->writeVTKCollection(); } else #endif if ( !emodel->isParallel() && tStep->giveNumber() >= 1 ) { // For non-parallel enabled OOFEM, then we only check for multiple steps. std::ostringstream pvdEntry; pvdEntry << "<DataSet timestep=\"" << tStep->giveIntrinsicTime() << "\" group=\"\" part=\"\" file=\"" << fname << "\"/>"; this->pvdBuffer.push_back(pvdEntry.str()); this->writeVTKCollection(); } } #ifndef __VTK_MODULE void VTKXMLExportModule :: exportPointDataHeader(FILE *stream, TimeStep *tStep) { int n; std :: string scalars, vectors, tensors; n = primaryVarsToExport.giveSize(); UnknownType type; for ( int i = 1; i <= n; i++ ) { type = ( UnknownType ) primaryVarsToExport.at(i); if ( ( type == DisplacementVector ) || ( type == EigenVector ) || ( type == VelocityVector ) ) { vectors += __UnknownTypeToString(type); vectors.append(" "); } else if ( ( type == FluxVector ) || ( type == PressureVector ) || ( type == Temperature ) ) { scalars += __UnknownTypeToString(type); scalars.append(" "); } else { OOFEM_ERROR2( "VTKXMLExportModule::exportPrimVarAs: unsupported UnknownType %s", __UnknownTypeToString(type) ); } } InternalStateType isttype; InternalStateValueType vtype; n = internalVarsToExport.giveSize(); // prepare header for ( int i = 1; i <= n; i++ ) { isttype = ( InternalStateType ) internalVarsToExport.at(i); vtype = giveInternalStateValueType(isttype); if ( vtype == ISVT_SCALAR ) { scalars += __InternalStateTypeToString(isttype); scalars.append(" "); } else if ( vtype == ISVT_VECTOR ) { vectors += __InternalStateTypeToString(isttype); vectors.append(" "); } else if ( ( vtype == ISVT_TENSOR_S3 ) || ( vtype == ISVT_TENSOR_S3E ) ) { tensors += __InternalStateTypeToString(isttype); tensors.append(" "); } else if ( vtype == ISVT_TENSOR_G ) { vectors += __InternalStateTypeToString(isttype); vectors.append(" "); } else { fprintf( stderr, "VTKXMLExportModule::exportIntVars: unsupported variable type %s\n", __InternalStateTypeToString(isttype) ); } } // print header fprintf( stream, "<PointData Scalars=\"%s\" Vectors=\"%s\" Tensors=\"%s\" >\n", scalars.c_str(), vectors.c_str(), tensors.c_str() ); }
void CrackExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { if ( !testTimeStepOutput(tStep) ) { return; } double crackLength_projection; double crackLength_sqrt; double crackWidth; double crackAngle; double elementLength; double damage; FloatArray crackVector; FloatMatrix princDir; FloatMatrix rotMatrix; FloatArray strainVector, princStrain; FloatArray output; double weight, totWeight; //InternalStateType vartype; Domain *d = emodel->giveDomain(1); int nelem = d->giveNumberOfElements(); //double index = tStep->giveNumber(); std::vector< FloatArray > pointsVector; // loop over elements for ( int ielem = 1; ielem <= nelem; ielem++ ) { Element *elem = d->giveElement(ielem); int csNumber = elem->giveCrossSection()->giveNumber(); if ( this->crossSections.containsSorted( csNumber ) ) { //if (true) { totWeight = 0.; crackWidth = 0.; crackLength_projection = 0.; crackLength_sqrt = 0.; crackAngle = 0.; for ( int i = 0; i < elem->giveNumberOfIntegrationRules(); i++ ) { IntegrationRule *iRule = elem->giveIntegrationRule(i); output.resize(5); for ( auto &gp: *iRule ) { IsotropicDamageMaterialStatus *matStatus = static_cast< IsotropicDamageMaterialStatus * >( gp->giveStatus() ); damage = matStatus->giveDamage(); //elem->giveIPValue(strainVector, gp, IST_StrainTensor, tStep); if ( damage > 0. ) { weight = elem->computeVolumeAround(gp); totWeight += weight; elementLength = matStatus->giveLe(); strainVector = matStatus->giveStrainVector(); matStatus->giveCrackVector(crackVector); crackVector.times(1./damage); princDir.resize(2,2); princDir.at(1,1) = crackVector.at(2); princDir.at(2,1) = -crackVector.at(1); princDir.at(1,2) = crackVector.at(1); princDir.at(2,2) = crackVector.at(2); // modify shear strain in order to allow transformation with the stress transformation matrix strainVector.at(3) /= 2.; StructuralMaterial :: givePlaneStressVectorTranformationMtrx(rotMatrix, princDir, false); princStrain.beProductOf(rotMatrix, strainVector); crackWidth += elementLength * princStrain.at(1) * damage * weight; crackLength_projection += elem->giveCharacteristicSize(gp, crackVector, ECSM_Projection) * weight; crackLength_sqrt += elem->giveCharacteristicSize(gp, crackVector, ECSM_SquareRootOfArea) * weight; if ( crackVector.at(1) != 0. ) { double contrib = atan( crackVector.at(2) / crackVector.at(1) ) * 180./3.1415926; if ( contrib < 0. ) { contrib += 180.; } else if ( contrib > 180. ) { contrib -= 180.; } crackAngle += contrib * weight; } else { crackAngle += 90. * weight; } #if 0 double length1 = elem->giveCharacteristicSize(gp, crackVector, ECSM_SquareRootOfArea); double length2 = elem->giveCharacteristicSize(gp, crackVector, ECSM_ProjectionCentered); double length3 = elem->giveCharacteristicSize(gp, crackVector, ECSM_Oliver1); double length4 = elem->giveCharacteristicSize(gp, crackVector, ECSM_Oliver1modified); double length5 = elem->giveCharacteristicSize(gp, crackVector, ECSM_Projection); #endif } else { crackWidth += 0.; crackLength_projection += 0.; crackLength_sqrt += 0.; crackAngle += 0.; } } if ( totWeight > 0. ) { crackWidth /= totWeight; crackLength_projection /= totWeight; crackLength_sqrt /= totWeight; crackAngle /= totWeight; } if ( crackWidth >= threshold ) { output.at(1) = ielem; output.at(2) = crackWidth; output.at(3) = crackAngle; output.at(4) = crackLength_projection; output.at(5) = crackLength_sqrt; pointsVector.push_back(output); } } } } // vyblejt do outputu std :: stringstream strCracks; strCracks << ".dat"; std :: string nameCracks = this->giveOutputBaseFileName(tStep) + strCracks.str(); writeToOutputFile(nameCracks, pointsVector); }
void HOMExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) { return; } Domain *d = emodel->giveDomain(1); int nelem = d->giveNumberOfElements(); double dV, VolTot = 0.; FloatArray vecState, vecFlow, sumFlow(3); FloatArray internalSource, capacity; FloatArray answerArr, answerArr1; FloatMatrix answerMtrx; IntArray Mask; FloatMatrix baseGCS; sumFlow.zero(); domainType domType = d->giveDomainType(); if ( domType == _HeatTransferMode || domType == _HeatMass1Mode ) { #ifdef __TM_MODULE double sumState = 0.; TransportElement *transpElem; for ( int ielem = 1; ielem <= nelem; ielem++ ) { Element *elem = d->giveElement(ielem); if ( this->matnum.giveSize() == 0 || this->matnum.contains( elem->giveMaterial()->giveNumber() ) ) { for ( GaussPoint *gp: *elem->giveDefaultIntegrationRulePtr() ) { dV = elem->computeVolumeAround(gp); VolTot += dV; elem->giveIPValue(vecState, gp, IST_Temperature, tStep); elem->giveIPValue(vecFlow, gp, IST_TemperatureFlow, tStep); sumState += vecState.at(1) * dV; vecFlow.resize(3); vecFlow.times(dV); sumFlow += vecFlow; } } } sumState *= ( 1. / VolTot * this->scale ); fprintf(this->stream, "%e % e ", tStep->giveTargetTime(), sumState); sumFlow.times(1. / VolTot * this->scale); fprintf( this->stream, "% e % e % e ", sumFlow.at(1), sumFlow.at(2), sumFlow.at(3) ); //add total heat for each material - accumulated energy due to material capacity (J for heat) and internal source (J for heat) internalSource.resize( d->giveNumberOfCrossSectionModels() ); capacity.resize( d->giveNumberOfCrossSectionModels() ); for ( int ielem = 1; ielem <= nelem; ielem++ ) { transpElem = static_cast< TransportElement * >( d->giveElement(ielem) ); transpElem->computeInternalSourceRhsVectorAt(answerArr, tStep, VM_Total); internalSource.at( transpElem->giveCrossSection()->giveNumber() ) += answerArr.sum(); transpElem->giveCharacteristicMatrix(answerMtrx, CapacityMatrix, tStep); transpElem->computeVectorOf(VM_Incremental, tStep, answerArr); answerArr1.beProductOf(answerMtrx, answerArr); capacity.at( transpElem->giveCrossSection()->giveNumber() ) -= answerArr1.sum(); } internalSource.times( tStep->giveTimeIncrement() ); internalSourceEnergy.add(internalSource); capacityEnergy.add(capacity); for ( int i = 1; i <= internalSourceEnergy.giveSize(); i++ ) { fprintf( this->stream, "% e ", internalSourceEnergy.at(i) ); } fprintf(this->stream, " "); for ( int i = 1; i <= capacityEnergy.giveSize(); i++ ) { fprintf( this->stream, "% e ", capacityEnergy.at(i) ); } fprintf(this->stream, "\n"); #endif } else { //structural analysis #ifdef __SM_MODULE StructuralElement *structElem; //int nnodes = d->giveNumberOfDofManagers(); FloatArray VecStrain, VecStress, VecEigStrain, VecEigStrainReduced, tempStrain(6), tempStress(6), tempEigStrain(6), SumStrain(6), SumStress(6), SumEigStrain(6), tempFloatAr, damage; double sumDamage = 0.; //stress and strain vectors are always in global c.s. SumStrain.zero(); //xx, yy, zz, yz, zx, xy SumStress.zero(); SumEigStrain.zero(); for ( int ielem = 1; ielem <= nelem; ielem++ ) { Element *elem = d->giveElement(ielem); tempStrain.zero(); tempStress.zero(); tempEigStrain.zero(); if ( this->matnum.giveSize() == 0 || this->matnum.contains( elem->giveMaterial()->giveNumber() ) ) { for ( GaussPoint *gp: *elem->giveDefaultIntegrationRulePtr() ) { structElem = static_cast< StructuralElement * >(elem); // structElem->computeResultingIPEigenstrainAt(VecEigStrain, tStep, gp, VM_Incremental); structElem->computeResultingIPEigenstrainAt(VecEigStrainReduced, tStep, gp, VM_Total); if ( VecEigStrainReduced.giveSize() == 0 ) { VecEigStrain.resize(0); } else { ( ( StructuralMaterial * ) structElem->giveMaterial() )->giveFullSymVectorForm( VecEigStrain, VecEigStrainReduced, gp->giveMaterialMode() ); } dV = elem->computeVolumeAround(gp); elem->giveIPValue(VecStrain, gp, IST_StrainTensor, tStep); elem->giveIPValue(VecStress, gp, IST_StressTensor, tStep); elem->giveIPValue(damage, gp, IST_DamageTensor, tStep); //truss element has strains and stresses in the first array so transform them to global coordinates ///@todo Should this be the job of giveIPValue to ensure that vectors are given in global c.s.? if ( dynamic_cast< Truss3d * >(elem) ) { MaterialMode mmode = _3dMat; tempStress.at(1) = VecStress.at(1); tempStrain.at(1) = VecStrain.at(1); if ( VecEigStrain.giveSize() ) { tempEigStrain.at(1) = VecEigStrain.at(1); } StressVector stressVector1(tempStress, mmode); //convert from array StressVector stressVector2(mmode); StrainVector strainVector1(tempStrain, mmode); //convert from array StrainVector strainVector2(mmode); StrainVector strainEigVector1(tempEigStrain, mmode); //convert from array StrainVector strainEigVector2(mmode); elem->giveLocalCoordinateSystem(baseGCS); stressVector1.transformTo(stressVector2, baseGCS, 0); strainVector1.transformTo(strainVector2, baseGCS, 0); strainEigVector1.transformTo(strainEigVector2, baseGCS, 0); stressVector2.convertToFullForm(VecStress); strainVector2.convertToFullForm(VecStrain); strainEigVector2.convertToFullForm(VecEigStrain); } VolTot += dV; VecStrain.times(dV); VecStress.times(dV); VecEigStrain.times(dV); if ( damage.giveSize() ) { //only for models with damage sumDamage += damage.at(1) * dV; } SumStrain.add(VecStrain); SumEigStrain.add(VecEigStrain); SumStress.add(VecStress); //VecStrain.printYourself(); //VecEigStrain.printYourself(); //SumStrain.printYourself(); } } } //averaging SumStrain.times(1. / VolTot * this->scale); SumEigStrain.times(1. / VolTot * this->scale); SumStress.times(1. / VolTot * this->scale); sumDamage *= ( 1. / VolTot ); //SumStrain.printYourself(); //SumEigStrain.printYourself(); //SumStress.printYourself(); fprintf( this->stream, "%f ", tStep->giveTargetTime() ); for ( double s: SumStrain ) { //strain fprintf( this->stream, "%06.5e ", s ); } fprintf(this->stream, " "); for ( double s: SumStress ) { //stress fprintf( this->stream, "%06.5e ", s ); } fprintf(this->stream, " "); for ( double s: SumEigStrain ) { //eigenstrain fprintf( this->stream, "%06.5e ", s ); } fprintf(this->stream, "Vol %06.5e ", VolTot); fprintf(this->stream, "AvrDamage %06.5e ", sumDamage); fprintf(this->stream, "\n"); #endif } fflush(this->stream); }
void GPExportModule :: doOutput(TimeStep *tStep, bool forcedOutput) { if ( !testTimeStepOutput(tStep) ) { return; } double weight; FloatArray gcoords, intvar; Domain *d = emodel->giveDomain(1); FILE *stream = this->giveOutputStream(tStep); // print the header fprintf(stream, "%%# gauss point data file\n"); fprintf(stream, "%%# output for time %g\n", tStep->giveTargetTime() ); fprintf(stream, "%%# variables: "); fprintf(stream, "%d ", vartypes.giveSize()); for ( auto &vartype : vartypes ) { fprintf( stream, "%d ", vartype ); } fprintf(stream, "\n %%# for interpretation see internalstatetype.h\n"); // loop over elements for ( auto &elem : d->giveElements() ) { //iRule = elem->giveDefaultIntegrationRulePtr(); //int numIntRules = elem->giveNumberOfIntegrationRules(); for ( int i = 0; i < elem->giveNumberOfIntegrationRules(); i++ ) { IntegrationRule *iRule = elem->giveIntegrationRule(i); // loop over Gauss points for ( GaussPoint *gp: *iRule ) { // export: // 1) element number // 2) material number ///@todo deprecated returns -1 // 3) Integration rule number // 4) Gauss point number // 5) contributing volume around Gauss point weight = elem->computeVolumeAround(gp); fprintf(stream, "%d %d %d %d %.6e ", elem->giveNumber(), -1, i + 1, gp->giveNumber(), weight); // export Gauss point coordinates if ( ncoords ) { // no coordinates exported if ncoords==0 elem->computeGlobalCoordinates( gcoords, gp->giveNaturalCoordinates() ); int nc = gcoords.giveSize(); if ( ncoords >= 0 ) { fprintf(stream, "%d ", ncoords); } else { fprintf(stream, "%d ", nc); } if ( ncoords > 0 && ncoords < nc ) { nc = ncoords; } for ( auto &c : gcoords ) { fprintf( stream, "%.6e ", c ); } for ( int ic = nc + 1; ic <= ncoords; ic++ ) { fprintf(stream, "%g ", 0.0); } } // export internal variables for ( auto vartype : vartypes ) { elem->giveIPValue(intvar, gp, ( InternalStateType )vartype, tStep); fprintf(stream, "%d ", intvar.giveSize()); for ( auto &val : intvar ) { fprintf( stream, "%.6e ", val ); } } fprintf(stream, "\n"); } } #if 0 // for CST elements write also nodal coordinates // (non-standard part, used only exceptionally) int nnode = elem->giveNumberOfNodes(); if ( nnode == 3 ) { for ( int inod = 1; inod <= 3; inod++ ) { fprintf( stream, "%f %f ", elem->giveNode(inod)->giveCoordinate(1), elem->giveNode(inod)->giveCoordinate(2) ); } } #endif } fclose(stream); }