int PreconditionerComposed::push_back (operatorPtr_Type& oper, const bool useInverse, const bool useTranspose ) { if (!M_prec.get() ) { M_prec.reset (new prec_Type (M_displayer.comm() ) ); } M_operVector.push_back (oper); LifeChrono chrono; epetraPrecPtr_Type prec; this->M_displayer.leaderPrint ( std::string ("ICP- Preconditioner type: ") + M_prec->Operator() [M_operVector.size() - 1]->preconditionerType() + std::string ("\n") ); this->M_displayer.leaderPrint ( "ICP- Computing preconditioner ... " ); chrono.start(); createPrec (oper, M_prec->OperatorView() [M_operVector.size() - 1]); chrono.stop(); this->M_displayer.leaderPrintMax ("done in ", chrono.diff() ); M_prec->replace (prec, useInverse, useTranspose); // \TODO to reset as push_back if ( M_prec->Operator().size() == M_operVector.size() ) { this->M_preconditionerCreated = true; } return EXIT_SUCCESS; }
Int SolverAztecOO::solveSystem ( const vector_type& rhsFull, vector_type& solution, matrix_ptrtype& baseMatrixForPreconditioner ) { bool retry ( true ); LifeChrono chrono; M_displayer->leaderPrint ( "SLV- Setting up the solver ... \n" ); if ( baseMatrixForPreconditioner.get() == 0 ) { M_displayer->leaderPrint ( "SLV- Warning: baseMatrixForPreconditioner is empty \n" ); } if ( !isPreconditionerSet() || !M_reusePreconditioner ) { buildPreconditioner ( baseMatrixForPreconditioner ); // do not retry if I am recomputing the preconditioner retry = false; } else { M_displayer->leaderPrint ( "SLV- Reusing precond ... \n" ); } Int numIter = solveSystem ( rhsFull, solution, M_preconditioner ); // If we do not want to retry, return now. // otherwise rebuild the preconditioner and solve again: if ( numIter < 0 && retry ) { chrono.start(); M_displayer->leaderPrint ( "SLV- Iterative solver failed, numiter = " , - numIter ); M_displayer->leaderPrint ( "SLV- maxIterSolver = " , M_maxIter ); M_displayer->leaderPrint ( "SLV- retrying: " ); buildPreconditioner ( baseMatrixForPreconditioner ); chrono.stop(); M_displayer->leaderPrintMax ( "done in " , chrono.diff() ); // Solving again, but only once (retry = false) numIter = solveSystem ( rhsFull, solution, M_preconditioner ); if ( numIter < 0 ) { M_displayer->leaderPrint ( " ERROR: Iterative solver failed again.\n" ); } } if ( std::abs (numIter) > M_maxIterForReuse ) { resetPreconditioner(); } return numIter; }
void ExporterEnsight<MeshType>::import (const Real& time) { this->M_timeSteps.push_back (time); ++this->M_steps; // typedef std::list< exporterData_Type >::iterator Iterator; this->computePostfix(); assert ( this->M_postfix.find ( "*" ) == std::string::npos ); if (!this->M_procId) { std::cout << " X- ExporterEnsight importing ..." << std::endl; } LifeChrono chrono; chrono.start(); for (typename super::dataVectorIterator_Type i = this->M_dataVector.begin(); i != this->M_dataVector.end(); ++i) { this->readVariable (*i); } chrono.stop(); if (!this->M_procId) { std::cout << " done in " << chrono.diff() << " s." << std::endl; } }
void LinearSolver::buildPreconditioner() { LifeChrono chrono; Real condest( -1 ); if( M_preconditioner ) { if( M_matrix.get() == 0 ) { M_displayer->leaderPrint( "SLV- ERROR: LinearSolver requires a matrix to build the preconditioner!\n" ); exit( 1 ); } else { chrono.start(); if( !M_silent ) M_displayer->leaderPrint( "SLV- Computing the preconditioner...\n" ); if ( M_baseMatrixForPreconditioner.get() == 0 ) { if( !M_silent ) M_displayer->leaderPrint( "SLV- Build the preconditioner using the problem matrix\n" ); M_preconditioner->buildPreconditioner( M_matrix ); } else { if( !M_silent ) M_displayer->leaderPrint( "SLV- Build the preconditioner using the base matrix provided\n" ); M_preconditioner->buildPreconditioner( M_baseMatrixForPreconditioner ); } condest = M_preconditioner->condest(); chrono.stop(); if( !M_silent ) M_displayer->leaderPrintMax( "SLV- Preconditioner computed in " , chrono.diff(), " s." ); if( !M_silent ) M_displayer->leaderPrint( "SLV- Estimated condition number " , condest, "\n" ); } } }
void WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryCauchyStressesCylindrical ( void ) { LifeChrono chrono; chrono.start(); UInt dim = this->M_FESpace->dim(); constructGlobalStressVector(); for ( UInt iDOF = 0; iDOF < ( UInt ) this->M_FESpace->dof().numTotalDof(); iDOF++ ) { if ( this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF) ) != -1 ) // The Global ID is on the calling processors { (* (this->M_sigma) ).Scale (0.0); //Extracting the gradient of U on the current DOF for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp ) { Int LIDid = this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF + iComp * dim + this->M_offset ) ); Int GIDid = this->M_displacement->blockMap().GID (static_cast<EpetraInt_Type> (LIDid) ); (* (this->M_sigma) ) (iComp, 0) = (*this->M_sigmaX) (GIDid); // (d_xX,d_yX,d_zX) (* (this->M_sigma) ) (iComp, 1) = (*this->M_sigmaY) (GIDid); // (d_xY,d_yY,d_zY) (* (this->M_sigma) ) (iComp, 2) = (*this->M_sigmaZ) (GIDid); // (d_xZ,d_yZ,d_zZ) } //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() ); //Save the eigenvalues in the global vector for ( UInt icoor = 0; icoor < this->M_FESpace->fieldDim(); ++icoor ) { Int LIDid = this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF + icoor * dim + this->M_offset) ); Int GIDid = this->M_displacement->blockMap().GID (static_cast<EpetraInt_Type> (LIDid) ); (* (this->M_globalEigenvalues) ) (GIDid) = this->M_eigenvaluesR[icoor]; } } } chrono.stop(); this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() ); }
void ExporterEnsight<MeshType>::postProcess (const Real& time) { // writing the geo file and the list of global IDs, but only upon the first instance if ( M_firstTimeStep ) { if (!this->M_multimesh) { writeAsciiGeometry ( this->M_postDir + this->M_prefix + this->M_me + ".geo" ); } writeGlobalIDs ( this->M_postDir + super::M_prefix + "_globalIDs" + this->M_me + ".scl" ); M_firstTimeStep = false; } // prepare the file postfix this->computePostfix(); // the postfix will be full of stars, if this time step is not going to generate a snapshot std::size_t found ( this->M_postfix.find ( "*" ) ); if ( found == std::string::npos ) { if (!this->M_procId) { std::cout << " X- ExporterEnsight post-processing ... " << std::flush; } LifeChrono chrono; chrono.start(); for (typename super::dataVectorIterator_Type i = this->M_dataVector.begin(); i != this->M_dataVector.end(); ++i) { // the "regime" attribute needs to be valid if ( i->regime() != exporterData_Type::NullRegime ) { writeAscii (*i); } // if the solution is steady, we do not need to export it at each time step if (i->regime() == exporterData_Type::SteadyRegime) { i->setRegime ( exporterData_Type::NullRegime ); } } // write an updated case file writeCase (time); // write an updated geo file, if needed if (this->M_multimesh) { writeAsciiGeometry ( this->M_postDir + this->M_prefix + this->M_postfix + this->M_me + ".geo" ); } chrono.stop(); if (!this->M_procId) { std::cout << " done in " << chrono.diff() << " s." << std::endl; } } }
void SolverAztecOO::buildPreconditioner ( matrix_ptrtype& preconditioner ) { LifeChrono chrono; Real condest (-1); chrono.start(); M_displayer->leaderPrint ( "SLV- Computing the precond ... " ); M_preconditioner->buildPreconditioner ( preconditioner ); condest = M_preconditioner->condest(); chrono.stop(); M_displayer->leaderPrintMax ( "done in " , chrono.diff() ); M_displayer->leaderPrint ( "SLV- Estimated condition number " , condest, "\n" ); }
void ExporterVTK<MeshType>::import(const Real& /*time*/) { this->computePostfix(); assert( this->M_postfix != "*****" ); if (!this->M_procId) std::cout << " X- ExporterVTK importing ..."<< std::endl; LifeChrono chrono; chrono.start(); for (typename super::dataVectorIterator_Type iData=this->M_dataVector.begin(); iData != this->M_dataVector.end(); ++iData) { this->readVTUFiles(*iData); } chrono.stop(); if (!this->M_procId) std::cout << " done in " << chrono.diff() << " s." << std::endl; }
int PreconditionerComposed::replace(operatorPtr_Type& oper, const UInt index, const bool useInverse, const bool useTranspose) { ASSERT(index <= M_operVector.size(), "PreconditionerComposed::replace: index too large"); M_operVector[index] = oper; LifeChrono chrono; //ifpack_prec_type prec; this->M_displayer.leaderPrint( std::string("ICP- Preconditioner type: ") + M_prec->Operator()[index]->preconditionerType() + std::string("\n") ); this->M_displayer.leaderPrint( "ICP- Computing preconditioner ... " ); chrono.start(); createPrec(oper, M_prec->OperatorView()[index]); chrono.stop(); this->M_displayer.leaderPrintMax("done in ", chrono.diff()); M_prec->replace(M_prec->Operator()[index], index, useInverse, useTranspose); return EXIT_SUCCESS; }
Int main (Int argc, char** argv) { //Setup main communicator boost::shared_ptr<Epetra_Comm> comm; #ifdef HAVE_MPI std::cout << "MPI Initialization" << std::endl; MPI_Init ( &argc, &argv ); #endif //MPI Preprocessing #ifdef EPETRA_MPI Int nprocs; Int rank; MPI_Comm_size ( MPI_COMM_WORLD, &nprocs ); MPI_Comm_rank ( MPI_COMM_WORLD, &rank ); if ( rank == 0 ) { std::cout << "MPI Processes: " << nprocs << std::endl; std::cout << "MPI Epetra Initialization ... " << std::endl; } comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) ); comm->Barrier(); #else std::cout << "MPI SERIAL Epetra Initialization ... " << std::endl; comm.reset ( new Epetra_SerialComm() ); #endif // ********************************* // Useful typedefs // ********************************* typedef MultiscaleModelFSI1D::physics_Type physics_Type; typedef MultiscaleModelFSI1D::flux_Type flux_Type; typedef MultiscaleModelFSI1D::source_Type source_Type; typedef MultiscaleModelFSI1D::bc_Type bc_Type; typedef bc_Type::bcFunction_Type bcFunction_Type; // ********************************* // Reading from data file // ********************************* GetPot command_line (argc, argv); // checking if we are checking for the nightly build const bool check = command_line.search (2, "-c", "--check"); string fileName = command_line.follow ("data", 2, "-f", "--file"); GetPot dataFile ( fileName ); // ********************************* // Build the 1D model // ********************************* MultiscaleModelFSI1D oneDModel; oneDModel.setCommunicator ( comm ); // Scale, Rotate, Translate 1D (if necessary) boost::array< Real, NDIM > geometryScale; boost::array< Real, NDIM > geometryRotate; boost::array< Real, NDIM > geometryTranslate; geometryScale[0] = dataFile ( "1D_Model/space_discretization/transform", 1., 0); geometryScale[1] = dataFile ( "1D_Model/space_discretization/transform", 1., 1); geometryScale[2] = dataFile ( "1D_Model/space_discretization/transform", 1., 2); geometryRotate[0] = dataFile ( "1D_Model/space_discretization/transform", 0., 3) * M_PI / 180; geometryRotate[1] = dataFile ( "1D_Model/space_discretization/transform", 0., 4) * M_PI / 180; geometryRotate[2] = dataFile ( "1D_Model/space_discretization/transform", 0., 5) * M_PI / 180; geometryTranslate[0] = dataFile ( "1D_Model/space_discretization/transform", 0., 6); geometryTranslate[1] = dataFile ( "1D_Model/space_discretization/transform", 0., 7); geometryTranslate[2] = dataFile ( "1D_Model/space_discretization/transform", 0., 8); oneDModel.setGeometry ( geometryScale, geometryRotate, geometryTranslate ); oneDModel.setupData ( fileName ); // ********************************* // BC for the 1D model // ********************************* // Set BC using BCInterface //oneDModel.GetBCInterface().FillHandler( fileName, "1D_Model" ); // Set BC using standard approach Sin sinus ( 0, 10, .01, 0.); bcFunction_Type sinusoidalFunction ( boost::bind ( &Sin::operator(), &sinus, _1 ) ); // Absorbing bc_Type::bcFunctionSolverDefinedPtr_Type absorbing ( new OneDFSIFunctionSolverDefinedAbsorbing ( OneDFSI::right, OneDFSI::W2 ) ); bcFunction_Type absorbingFunction ( boost::bind ( &OneDFSIFunctionSolverDefinedAbsorbing::operator(), dynamic_cast<OneDFSIFunctionSolverDefinedAbsorbing*> ( & ( *absorbing ) ), _1, _2 ) ); // BC to test A_from_P conversion //Constant constantArea( 1.00 ); //bcFunction_Type constantAreaFunction( boost::bind( &Constant::operator(), &constantArea, _1 ) ); //Constant constantPressure( 24695.0765959599 ); //bcFunction_Type constantPressureFunction( boost::bind( &Constant::operator(), &constantPressure, _1 ) ); oneDModel.bc().setBC ( OneDFSI::left, OneDFSI::first, OneDFSI::Q, sinusoidalFunction ); oneDModel.bc().setBC ( OneDFSI::right, OneDFSI::first, OneDFSI::W2, absorbingFunction ); //oneDModel.bc().setBC( OneDFSI::right, OneDFSI::first, OneDFSI::A, constantAreaFunction ); //oneDModel.bc().setBC( OneDFSI::right, OneDFSI::first, OneDFSI::P, constantPressureFunction ); oneDModel.setupModel(); absorbing->setSolution ( oneDModel.solution() ); absorbing->setFluxSource ( oneDModel.flux(), oneDModel.source() ); // ********************************* // Tempolar loop // ********************************* std::cout << "\nTemporal loop:" << std::endl; LifeChrono chronoTotal; LifeChrono chronoSystem; LifeChrono chronoIteration; Int count = 0; chronoTotal.start(); for ( ; oneDModel.data().dataTime()->canAdvance() ; oneDModel.data().dataTime()->updateTime(), ++count ) { std::cout << std::endl << "--------- Iteration " << count << " time = " << oneDModel.data().dataTime()->time() << std::endl; chronoIteration.start(); if ( oneDModel.data().dataTime()->isFirstTimeStep() ) { oneDModel.buildModel(); } else { oneDModel.updateModel(); } chronoSystem.start(); oneDModel.solveModel(); chronoSystem.stop(); oneDModel.updateSolution(); //Save solution if ( count % 50 == 0 || oneDModel.data().dataTime()->isLastTimeStep() ) { oneDModel.saveSolution(); } chronoIteration.stop(); std::cout << " System solved in " << chronoSystem.diff() << " s, (total time " << chronoIteration.diff() << " s)." << std::endl; } chronoTotal.stop(); std::cout << std::endl << " Simulation ended successfully in " << chronoTotal.diff() << " s" << std::endl; #ifdef HAVE_MPI std::cout << "MPI Finalization" << std::endl; MPI_Finalize(); #endif if ( check ) { bool ok = true; Int rightNodeID = oneDModel.solver()->boundaryDOF ( OneDFSI::right ); ok = ok && checkValue ( 0.999998 , (*oneDModel.solution ("A") ) [rightNodeID]); ok = ok && checkValue (-0.00138076, (*oneDModel.solution ("Q") ) [rightNodeID]); ok = ok && checkValue (-0.00276153, (*oneDModel.solution ("W1") ) [rightNodeID]); ok = ok && checkValue ( 0.00000000, (*oneDModel.solution ("W2") ) [rightNodeID]); ok = ok && checkValue ( 0.999999 , (*oneDModel.solution ("A") ) [rightNodeID - 1]); ok = ok && checkValue (-0.00040393, (*oneDModel.solution ("Q") ) [rightNodeID - 1]); ok = ok && checkValue (-0.00080833, (*oneDModel.solution ("W1") ) [rightNodeID - 1]); ok = ok && checkValue ( 0.00000045, (*oneDModel.solution ("W2") ) [rightNodeID - 1]); if (ok) { std::cout << "Test successful" << std::endl; return 0; } else { std::cout << "Test unsuccessful" << std::endl; return -1; } } else { return 0; } }
void Heart::computeRhs ( vector_Type& rhs, HeartBidomainSolver< mesh_Type >& electricModel, boost::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel, HeartBidomainData& data ) { bool verbose = (M_heart_fct->M_comm->MyPID() == 0); if (verbose) { std::cout << " f- Computing Rhs ... " << "\n" << std::flush; } LifeChrono chrono; chrono.start(); //! u, w with repeated map vector_Type uVecRep (electricModel.solutionTransmembranePotential(), Repeated); ionicModel->updateRepeated(); VectorElemental elvec_Iapp ( electricModel.potentialFESpace().fe().nbFEDof(), 2 ), elvec_u ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ), elvec_Iion ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ); for (UInt iVol = 0; iVol < electricModel.potentialFESpace().mesh()->numVolumes(); ++iVol) { electricModel.potentialFESpace().fe().updateJacQuadPt ( electricModel.potentialFESpace().mesh()->volumeList ( iVol ) ); elvec_u.zero(); elvec_Iion.zero(); elvec_Iapp.zero(); UInt eleIDu = electricModel.potentialFESpace().fe().currentLocalId(); UInt nbNode = ( UInt ) electricModel.potentialFESpace().fe().nbFEDof(); for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ ) { Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode ); elvec_u.vec() [ iNode ] = uVecRep[ig]; } UInt eleID = electricModel.potentialFESpace().fe().currentLocalId(); ionicModel->updateElementSolution (eleID); ionicModel->computeIonicCurrent (data.membraneCapacitance(), elvec_Iion, elvec_u, electricModel.potentialFESpace() ); //! Computing Iapp AssemblyElemental::source (M_heart_fct->stimulus(), elvec_Iapp, electricModel.potentialFESpace().fe(), data.time(), 0); AssemblyElemental::source (M_heart_fct->stimulus(), elvec_Iapp, electricModel.potentialFESpace().fe(), data.time(), 1); UInt totalUDof = electricModel.potentialFESpace().map().map (Unique)->NumGlobalElements(); for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ ) { Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode ); rhs.sumIntoGlobalValues (ig, elvec_Iapp.vec() [iNode] + data.volumeSurfaceRatio() * elvec_Iion.vec() [iNode] ); rhs.sumIntoGlobalValues (ig + totalUDof, -elvec_Iapp.vec() [iNode + nbNode] - data.volumeSurfaceRatio() * elvec_Iion.vec() [iNode] ); } } rhs.globalAssemble(); rhs += electricModel.matrMass() * data.volumeSurfaceRatio() * data.membraneCapacitance() * electricModel.BDFIntraExtraPotential().time_der (data.timeStep() ); MPI_Barrier (MPI_COMM_WORLD); chrono.stop(); if (verbose) { std::cout << "done in " << chrono.diff() << " s." << std::endl; } }
Real darcy_nonlinear::run() { using namespace dataProblem; // Life chonos LifeChrono chronoTotal; LifeChrono chronoReadAndPartitionMesh; LifeChrono chronoBoundaryCondition; LifeChrono chronoFiniteElementSpace; LifeChrono chronoProblem; LifeChrono chronoProcess; LifeChrono chronoError; // Displayer to print on screen boost::shared_ptr < Displayer > displayer ( new Displayer ( Members->comm ) ); // Start chronoTotal for measure the total time for the computation chronoTotal.start(); // Reading from data file GetPot dataFile ( Members->data_file_name.c_str() ); // // The Darcy Solver // displayer->leaderPrint ( "The Darcy solver\n" ); // Start chronoReadAndPartitionMesh for measure the total time for the creation of the local meshes chronoReadAndPartitionMesh.start(); // Create the data file darcyDataPtr_Type darcyData ( new darcyData_Type ); // Set up the data darcyData->setup ( dataFile ); // Create a Teuchos parameter list for the linear algebra. darcyData_Type::paramListPtr_Type linearAlgebraList = Teuchos::rcp ( new darcyData_Type::paramList_Type ); linearAlgebraList = Teuchos::getParametersFromXmlFile ( Members->xml_file_name ); // Set the parameter list into the data darcy. darcyData->setLinearAlgebraList ( linearAlgebraList ); // Create the mesh file handler MeshData meshData; // Set up the mesh file meshData.setup ( dataFile, Members->discretization_section + "/space_discretization"); // Create the the mesh regionMeshPtr_Type fullMeshPtr ( new regionMesh_Type ( Members->comm ) ); // Select if the mesh is structured or not if ( meshData.meshType() != "structured" ) { // Set up the mesh readMesh ( *fullMeshPtr, meshData ); } else { // Section of the structured mesh const std::string structuredSection = Members->discretization_section + "/space_discretization/"; // Set up the structured mesh regularMesh2D ( *fullMeshPtr, 0, dataFile ( ( structuredSection + "nx" ).data(), 4 ), dataFile ( ( structuredSection + "ny" ).data(), 4 ), dataFile ( ( structuredSection + "verbose" ).data(), false ), dataFile ( ( structuredSection + "lx" ).data(), 1. ), dataFile ( ( structuredSection + "ly" ).data(), 1. ) ); } // Create the local mesh ( local scope used to delete the meshPart object ) regionMeshPtr_Type meshPtr; { // Create the partitioner MeshPartitioner< regionMesh_Type > meshPart; // Partition the mesh using ParMetis meshPart.doPartition ( fullMeshPtr, Members->comm ); // Get the local mesh meshPtr = meshPart.meshPartition(); } // Stop chronoReadAndPartitionMesh chronoReadAndPartitionMesh.stop(); // The leader process print chronoReadAndPartitionMesh displayer->leaderPrint ( "Time for read and partition the mesh ", chronoReadAndPartitionMesh.diff(), "\n" ); // Create the boundary conditions // Start chronoBoundaryCondition for measure the total time for create the boundary conditions chronoBoundaryCondition.start(); bcHandlerPtr_Type bcDarcy ( new bcHandler_Type ); setBoundaryConditions ( bcDarcy ); // Stop chronoBoundaryCondition chronoBoundaryCondition.stop(); // The leader process print chronoBoundaryCondition displayer->leaderPrint ( "Time for create the boundary conditions handler ", chronoBoundaryCondition.diff(), "\n" ); // Create the solution spaces // Start chronoFiniteElementSpace for measure the total time for create the finite element spaces chronoFiniteElementSpace.start(); // Primal solution parameters const ReferenceFE* refFE_primal ( static_cast<ReferenceFE*> (NULL) ); const QuadratureRule* qR_primal ( static_cast<QuadratureRule*> (NULL) ); const QuadratureRule* bdQr_primal ( static_cast<QuadratureRule*> (NULL) ); refFE_primal = &feTriaP0; qR_primal = &quadRuleTria4pt; bdQr_primal = &quadRuleSeg1pt; // Dual solution parameters const ReferenceFE* refFE_dual ( static_cast<ReferenceFE*> (NULL) ); const QuadratureRule* qR_dual ( static_cast<QuadratureRule*> (NULL) ); const QuadratureRule* bdQr_dual ( static_cast<QuadratureRule*> (NULL) ); refFE_dual = &feTriaRT0; qR_dual = &quadRuleTria4pt; bdQr_dual = &quadRuleSeg1pt; // Interpolate of dual solution parameters const ReferenceFE* refFE_dualInterpolate ( static_cast<ReferenceFE*> (NULL) ); const QuadratureRule* qR_dualInterpolate ( static_cast<QuadratureRule*> (NULL) ); const QuadratureRule* bdQr_dualInterpolate ( static_cast<QuadratureRule*> (NULL) ); refFE_dualInterpolate = &feTriaP0; qR_dualInterpolate = &quadRuleTria4pt; bdQr_dualInterpolate = &quadRuleSeg1pt; // Hybrid solution parameters // hybrid const ReferenceFE* refFE_hybrid ( static_cast<ReferenceFE*> (NULL) ); const QuadratureRule* qR_hybrid ( static_cast<QuadratureRule*> (NULL) ); const QuadratureRule* bdQr_hybrid ( static_cast<QuadratureRule*> (NULL) ); refFE_hybrid = &feTriaRT0Hyb; qR_hybrid = &quadRuleTria4pt; bdQr_hybrid = &quadRuleSeg1pt; // Finite element space of the primal variable fESpacePtr_Type p_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_primal, *qR_primal, *bdQr_primal, 1, Members->comm ) ); // Finite element space of the dual variable fESpacePtr_Type u_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_dual, *qR_dual, *bdQr_dual, 1, Members->comm ) ); // Finite element space of the hybrid variable fESpacePtr_Type hybrid_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_hybrid, *qR_hybrid, *bdQr_hybrid, 1, Members->comm ) ); // Finite element space of the interpolation of dual variable fESpacePtr_Type uInterpolate_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_dualInterpolate, *qR_dualInterpolate, *bdQr_dualInterpolate, 2, Members->comm ) ); // Stop chronoFiniteElementSpace chronoFiniteElementSpace.stop(); // The leader process print chronoFiniteElementSpace displayer->leaderPrint ( "Time for create the finite element spaces ", chronoFiniteElementSpace.diff(), "\n" ); // Start chronoProblem for measure the total time for create the problem chronoProblem.start(); // Instantiation of the DarcySolver class darcySolver_Type darcySolver; // Stop chronoProblem chronoProblem.stop(); // The leader process print chronoProblem displayer->leaderPrint ( "Time for create the problem ", chronoProblem.diff(), "\n" ); // Process the problem // Start chronoProcess for measure the total time for the simulation chronoProcess.start (); // Set the data for the solver. darcySolver.setData ( darcyData ); // Set the displayer. darcySolver.setDisplayer ( displayer ); // Setup phase for the linear solver darcySolver.setup (); // Create the fields for the solver // Scalar field for primal variable scalarFieldPtr_Type primalField ( new scalarField_Type ( p_FESpacePtr ) ); // Scalar field for dual variable scalarFieldPtr_Type dualField ( new scalarField_Type ( u_FESpacePtr ) ); // Scalar field for hybrid variable scalarFieldPtr_Type hybridField ( new scalarField_Type ( hybrid_FESpacePtr ) ); // Vector for the interpolated dual solution vectorFieldPtr_Type dualInterpolated ( new vectorField_Type ( uInterpolate_FESpacePtr, Repeated ) ); // Set the field for the solver // Set the h darcySolver.setHybridField ( hybridField ); // Set the primal field darcySolver.setPrimalField ( primalField ); // Set the dual field darcySolver.setDualField ( dualField ); // Set the source term scalarFctPtr_Type scalarSourceFct ( new scalarSource ); darcySolver.setScalarSource ( scalarSourceFct ); // Set the vector source term vectorFctPtr_Type vectorSourceFct ( new vectorSource ); darcySolver.setVectorSource ( vectorSourceFct ); // Set the reaction term scalarFctPtr_Type reactionTermFct ( new reactionTerm ); darcySolver.setReactionTerm ( reactionTermFct ); // Set the inverse of the permeability matrixFctPtr_Type inversePermeabilityFct ( new inversePermeability ); darcySolver.setInversePermeability ( inversePermeabilityFct ); // Set the initial primal variable scalarFctPtr_Type initialPrimalFct ( new initialCondition ); darcySolver.setInitialPrimal ( initialPrimalFct ); // Set the mass function scalarFctPtr_Type massFct ( new massFunction ); darcySolver.setMass ( massFct ); // Set the boudary conditions darcySolver.setBoundaryConditions ( bcDarcy ); // Set the exporter for the solution boost::shared_ptr< Exporter< regionMesh_Type > > exporter; // Shared pointer used in the exporter for the primal solution vectorPtr_Type primalExporter; // Shared pointer used in the exporter for the dual solution vectorPtr_Type dualExporter; // Type of the exporter std::string const exporterType = dataFile ( "exporter/type", "none" ); // The name of the file const std::string exporterFileName = dataFile ( "exporter/file_name", "PressureVelocity" ); // Choose the exporter #ifdef HAVE_HDF5 if ( exporterType.compare ("hdf5") == 0 ) { exporter.reset ( new ExporterHDF5 < regionMesh_Type > ( dataFile, exporterFileName ) ); } else #endif { exporter.reset ( new ExporterEmpty < regionMesh_Type > ( dataFile, exporterFileName ) ); } // Set directory where to save the solution exporter->setPostDir ( dataFile ( "exporter/folder", "./" ) ); exporter->setMeshProcId ( meshPtr, Members->comm->MyPID() ); // Set the exporter primal pointer primalExporter.reset ( new vector_Type ( primalField->getVector(), exporter->mapType() ) ); // Add the primal variable to the exporter exporter->addVariable ( ExporterData < regionMesh_Type >::ScalarField, dataFile ( "exporter/name_primal", "Pressure" ), p_FESpacePtr, primalExporter, static_cast<UInt> ( 0 ), ExporterData < regionMesh_Type >::UnsteadyRegime, ExporterData < regionMesh_Type >::Cell ); // Set the exporter dual pointer dualExporter.reset ( new vector_Type ( dualInterpolated->getVector(), exporter->mapType() ) ); // Add the variable to the exporter exporter->addVariable ( ExporterData < regionMesh_Type >::VectorField, dataFile ( "exporter/name_dual", "Velocity" ), uInterpolate_FESpacePtr, dualExporter, static_cast<UInt> ( 0 ), ExporterData < regionMesh_Type >::UnsteadyRegime, ExporterData < regionMesh_Type >::Cell ); // Display the total number of unknowns displayer->leaderPrint ( "Number of unknowns : ", hybrid_FESpacePtr->map().map ( Unique )->NumGlobalElements(), "\n" ); // Export the partitioning exporter->exportPID ( meshPtr, Members->comm ); // Copy the initial primal to the exporter *primalExporter = primalField->getVector (); // Save the initial primal solution into the exporter exporter->postProcess ( darcyData->dataTimePtr()->initialTime() ); // Define if the current time is the last time step. bool isLastTimeStep ( false ); // Define the end time const Real endTime = darcyData->dataTimePtr()->endTime(); // Define the tolerance for the elapsed time const Real tolTime = 1e-10; // Take the current time. Real currentTime = darcyData->dataTimePtr()->time(); // A loop for the simulation while ( darcyData->dataTimePtr()->time() < endTime && !isLastTimeStep ) { // Take the left time. const Real leftTime = endTime - currentTime; // Check if the time step is consistent if ( darcyData->dataTimePtr()->timeStep() > leftTime + tolTime ) { // Compute the last time step. darcyData->dataTimePtr()->setTimeStep ( leftTime ); // This is the last time step in the simulation isLastTimeStep = true; } // Advance the current time of \Delta t. darcyData->dataTimePtr()->updateTime(); // Take the current time. currentTime = darcyData->dataTimePtr()->time(); // The leader process prints the temporal data. if ( displayer->isLeader() ) { darcyData->dataTimePtr()->showMe(); } // Solve the problem. darcySolver.solve (); // Save the solutions. // Copy the primal solution to the exporter. *primalExporter = primalField->getVector (); // Interpolate the dual vector field spammed as Raviart-Thomas into a P0 vector field. dualInterpolated->getVector() = uInterpolate_FESpacePtr->feToFEInterpolate ( *u_FESpacePtr, dualField->getVector() ); // Copy the dual interpolated solution to the exporter. *dualExporter = dualInterpolated->getVector(); // Save the solution into the exporter. exporter->postProcess ( currentTime ); } // Stop chronoProcess chronoProcess.stop(); // The leader process print chronoProcess displayer->leaderPrint ( "Time for process ", chronoProcess.diff(), "\n" ); // Compute the errors // For non time dependences problem the time where the errors are computed is useless, // but thanks to common interface we handle both cases. // Start chronoError for measure the total time for computing the errors. chronoError.start(); // Compute the error L2 norms Real primalL2Norm (0), exactPrimalL2Norm (0), primalL2Error (0), primalL2RelativeError (0); Real dualL2Norm (0), exactDualL2Norm (0), dualL2Error (0), dualL2RelativeError (0); // Norms and errors for the pressure displayer->leaderPrint ( "\nPRESSURE ERROR\n" ); // Compute the L2 norm for the primal solution primalL2Norm = p_FESpacePtr->l2Norm ( primalField->getVector () ); // Display the L2 norm for the primal solution displayer->leaderPrint ( " L2 norm of primal unknown: ", primalL2Norm, "\n" ); // Compute the L2 norm for the analytical primal exactPrimalL2Norm = p_FESpacePtr->l2NormFunction ( Members->getAnalyticalSolution(), darcyData->dataTimePtr()->endTime() ); // Display the L2 norm for the analytical primal displayer->leaderPrint ( " L2 norm of primal exact: ", exactPrimalL2Norm, "\n" ); // Compute the L2 error for the primal solution primalL2Error = p_FESpacePtr->l2ErrorWeighted ( Members->getAnalyticalSolution(), primalField->getVector(), Members->getUOne(), darcyData->dataTimePtr()->endTime() ); // Display the L2 error for the primal solution displayer->leaderPrint ( " L2 error of primal unknown: ", primalL2Error, "\n" ); // Compute the L2 realative error for the primal solution primalL2RelativeError = primalL2Error / exactPrimalL2Norm; // Display the L2 relative error for the primal solution displayer->leaderPrint ( " L2 relative error of primal unknown: ", primalL2RelativeError, "\n" ); // Norms and errors for the interpolated dual displayer->leaderPrint ( "\nINTERPOLATED DARCY VELOCITY ERROR\n" ); // Compute the L2 norm for the interpolated dual solution dualL2Norm = uInterpolate_FESpacePtr->l2Norm ( dualInterpolated->getVector() ); // Display the L2 norm for the interpolated dual solution displayer->leaderPrint ( " L2 norm of dual unknown: ", dualL2Norm, "\n" ); // Compute the L2 norm for the analytical dual exactDualL2Norm = uInterpolate_FESpacePtr->l2NormFunction ( Members->getAnalyticalFlux(), darcyData->dataTimePtr()->endTime() ); // Display the L2 norm for the analytical dual displayer->leaderPrint ( " L2 norm of dual exact: ", exactDualL2Norm, "\n" ); // Compute the L2 error for the dual solution dualL2Error = uInterpolate_FESpacePtr->l2Error ( Members->getAnalyticalFlux(), dualInterpolated->getVector(), darcyData->dataTimePtr()->endTime(), NULL ); // Display the L2 error for the dual solution displayer->leaderPrint ( " L2 error of dual unknown: ", dualL2Error, "\n" ); // Compute the L2 relative error for the dual solution dualL2RelativeError = dualL2Error / exactDualL2Norm; // Display the L2 relative error for the dual solution displayer->leaderPrint ( " L2 relative error of Dual unknown: ", dualL2RelativeError, "\n" ); // Stop chronoError chronoError.stop(); // The leader process print chronoError displayer->leaderPrint ( "Time for compute errors ", chronoError.diff(), "\n" ); // Stop chronoTotal chronoTotal.stop(); // The leader process print chronoTotal displayer->leaderPrint ( "Total time for the computation ", chronoTotal.diff(), "\n" ); // Return the error, needed for the succes/failure of the test return primalL2Error; } // run
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() ); }
void WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryDisplacementCylindrical ( void ) { LifeChrono chrono; this->M_displayer->leaderPrint (" \n*********************************\n "); this->M_displayer->leaderPrint (" Performing the analysis recovering the displacement..., ", this->M_dataMaterial->solidType() ); this->M_displayer->leaderPrint (" \n*********************************\n "); solutionVectPtr_Type grDisplX ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) ); solutionVectPtr_Type grDisplY ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) ); solutionVectPtr_Type grDisplZ ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) ); //Compute the deformation gradient tensor F of the displ field super::computeDisplacementGradient ( grDisplX, grDisplY, grDisplZ); solutionVect_Type grXRep (*grDisplX, Repeated); solutionVect_Type grYRep (*grDisplY, Repeated); solutionVect_Type grZRep (*grDisplZ, Repeated); solutionVect_Type dRep (* (this->M_displacement), Repeated); //For each of the DOF, the Cauchy tensor is computed. //Therefore the tensor C,P, \sigma are computed for each DOF chrono.start(); for ( UInt i (0); i < this->M_FESpace->mesh()->numVolumes(); ++i ) { //Setup quantities this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) ); UInt eleID = this->M_FESpace->fe().currentLocalId(); this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID(); //store the local \grad(u) matrix_Type gradientDispl ( this->M_FESpace->fieldDim(), this->M_FESpace->fieldDim() ); gradientDispl.Scale ( 0.0 ); //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; gradientDispl (iComp, 0) = grXRep[ig]; gradientDispl (iComp, 1) = grYRep[ig]; gradientDispl (iComp, 2) = grZRep[ig]; } //Reinitialization of matrices and arrays ( * (this->M_cofactorF) ).Scale (0.0); ( * (this->M_firstPiola) ).Scale (0.0); ( * (this->M_sigma) ).Scale (0.0); //Moving to cylindrical coordinates moveToCylindricalCoordinates ( gradientDispl, 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 ( UInt j (0); j < this->M_eigenvaluesI.size(); ++j ) { sum += std::abs ( this->M_eigenvaluesI[j] ); } ASSERT ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" ); std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() ); std::cout << "Saving eigenvalues" << i << std::endl; //Save the eigenvalues in the global vector for ( UInt icoor = 0; icoor < this->M_FESpace->fieldDim(); ++icoor ) { UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + icoor * this->M_FESpace->dim() + this->M_offset; (* (this->M_globalEigenvalues) ) (ig) = this->M_eigenvaluesR[icoor]; // Int LIDid = this->M_displacement->blockMap().LID(ig); // if( this->M_globalEigenvalues->blockMap().LID(ig) != -1 ) // { // Int GIDid = this->M_globalEigenvalues->blockMap().GID(LIDid); // } } } } chrono.stop(); this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() ); }
void ExporterVTK<MeshType>::postProcess (const Real& time) { // typedef std::list< ExporterData >::iterator Iterator; this->computePostfix(); std::size_t found ( this->M_postfix.find ( "*" ) ); if ( found == string::npos ) { if (this->M_procId == 0) { std::cout << " X- ExporterVTK post-processing" << std::flush; } LifeChrono chrono; chrono.start(); this->M_timeSteps.push_back (time); for (typename super::dataVectorIterator_Type iData = this->M_dataVector.begin(); iData != this->M_dataVector.end(); ++iData) { std::ofstream vtkFile; std::stringstream buffer (""); // a unique PVTU file + a time collection is produced by the leader process if (this->M_procId == 0) { composePVTUStream (*iData, buffer); std::string vtkPFileName ( this->M_prefix + "_" + iData->variableName() + this->M_postfix + ".pvtu" ); std::string vtkPFileNameWithDir (this->M_postDir + vtkPFileName); std::ofstream vtkPFile; vtkPFile.open ( vtkPFileNameWithDir.c_str() ); ASSERT (vtkPFile.is_open(), "There is an error while opening " + vtkPFileName ); ASSERT (vtkPFile.good(), "There is an error while writing to " + vtkPFileName ); vtkPFile << buffer.str(); vtkPFile.close(); buffer.str (""); this->M_pvtuFiles[iData->variableName()].push_back (vtkPFileName); } // redundant. should be done just the first time std::map<UInt, UInt> ltgPointsMap, gtlPointsMap; std::vector<Vector> pointsCoords; createPointsMaps ( iData->feSpacePtr(), gtlPointsMap, ltgPointsMap, pointsCoords ); composeVTUHeaderStream ( gtlPointsMap.size(), buffer ); composeVTUGeoStream ( iData->feSpacePtr(), gtlPointsMap, pointsCoords, buffer ); composeTypeDataHeaderStream (iData->where(), buffer); composeDataArrayStream (*iData, ltgPointsMap, buffer); composeTypeDataFooterStream (iData->where(), buffer); composeVTUFooterStream ( buffer ); // each process writes its own file std::string filename ( this->M_postDir + this->M_prefix + "_" + iData->variableName() + this->M_postfix + "." + this->M_procId + ".vtu" ); vtkFile.open ( filename.c_str() ); ASSERT (vtkFile.is_open(), "There is an error while opening " + filename ); ASSERT (vtkFile.good(), "There is an error while writing to " + filename ); vtkFile << buffer.str(); vtkFile.close(); buffer.str (""); } chrono.stop(); if (!this->M_procId) { std::cout << "...done in " << chrono.diff() << " s." << std::endl; } } }
// =================================================== //! Methods // =================================================== void problem::run() { typedef RegionMesh<LinearTetra> mesh_Type; typedef VenantKirchhoffViscoelasticSolver< mesh_Type >::vector_type vector_Type; typedef boost::shared_ptr<vector_Type> vectorPtr_Type; typedef boost::shared_ptr< TimeAdvance< vector_Type > > TimeAdvance_type; typedef FESpace< mesh_Type, MapEpetra > FESpace_type; typedef boost::shared_ptr<FESpace_type> FESpace_ptrtype; bool verbose = (members->comm->MyPID() == 0); // // VenantKirchhoffViscoelasticData // GetPot dataFile( members->data_file_name.c_str() ); boost::shared_ptr<VenantKirchhoffViscoelasticData> dataProblem(new VenantKirchhoffViscoelasticData( )); dataProblem->setup(dataFile, "problem"); MeshData meshData; meshData.setup(dataFile, "problem/space_discretization"); boost::shared_ptr<mesh_Type > fullMeshPtr( new mesh_Type( members->comm ) ); readMesh(*fullMeshPtr, meshData); boost::shared_ptr<mesh_Type > localMeshPtr; { MeshPartitioner< mesh_Type > meshPart( fullMeshPtr, members->comm ); localMeshPtr = meshPart.meshPartition(); } // // The Problem Solver // if (verbose) std::cout << "The Problem Solver" << std::flush; // Scalar Solution Space: std::string Order = dataFile( "problem/space_discretization/order", "P1"); if ( Order.compare("P1") == 0 ) { if (verbose) std::cout << " Space order : P1" << std::flush; } else if ( Order.compare("P2") == 0 ) { if (verbose) std::cout << " Space order : P2"; } if (verbose) std::cout << std::endl; // finite element space of the solution // finite element space of the solution std::string dOrder = dataFile( "problem/space_discretization/order", "P1"); FESpace_ptrtype feSpace( new FESpace_type(localMeshPtr,dOrder,1,members->comm) ); // instantiation of the VenantKirchhoffViscoelasticSolver class VenantKirchhoffViscoelasticSolver< mesh_Type > problem; problem.setup(dataProblem, feSpace, members->comm); problem.setDataFromGetPot(dataFile); // the boundary conditions BCFunctionBase uZero ( members->getUZero() ); BCFunctionBase uEx(uexact); BCHandler bcH; bcH.addBC( "Top", TOP, Essential, Full, uEx, 1 ); bcH.addBC( "Bottom", BOTTOM, Essential, Full, uEx, 1 ); bcH.addBC( "Left", LEFT, Essential, Full, uEx, 1 ); bcH.addBC( "Right", RIGHT, Essential, Full, uEx, 1 ); bcH.addBC( "Front", FRONT, Essential, Full, uEx, 1 ); bcH.addBC( "Back", BACK, Essential, Full, uEx, 1 ); std::ofstream out_norm; if (verbose) { out_norm.open("norm.txt"); out_norm << " time " <<" L2_Error " <<" H1_Error " <<" L2_RelError " <<" H1_RelError \n"; out_norm.close(); } LifeChrono chrono; std::string TimeAdvanceMethod = dataFile( "problem/time_discretization/method", "Newmark"); TimeAdvance_type timeAdvance( TimeAdvanceFactory::instance().createObject( TimeAdvanceMethod ) ); UInt OrderDev = 1; //! initialization of parameters of time Advance method: if (TimeAdvanceMethod =="Newmark") timeAdvance->setup( dataProblem->dataTimeAdvance()->coefficientsNewmark() , OrderDev); if (TimeAdvanceMethod =="BDF") timeAdvance->setup(dataProblem->dataTimeAdvance()->orderBDF() , OrderDev); Real dt = dataProblem->dataTime()->timeStep(); Real T = dataProblem->dataTime()->endTime(); chrono.start(); dataProblem->setup(dataFile, "problem"); double alpha = timeAdvance->coefficientFirstDerivative( 0 ) / ( dataProblem->dataTime()->timeStep()); problem.buildSystem(alpha); MPI_Barrier(MPI_COMM_WORLD); if (verbose ) std::cout << "ok." << std::endl; // building some vectors: MapEpetra uMap = problem.solution()->map(); // computing the rhs vector_Type rhs ( uMap, Unique ); vector_Type rhsV( uMap, Unique ); // postProcess boost::shared_ptr< Exporter<mesh_Type > > exporter; std::string const exporterType = dataFile( "exporter/type", "ensight"); #ifdef HAVE_HDF5 if (exporterType.compare("hdf5") == 0) exporter.reset( new ExporterHDF5<mesh_Type > ( dataFile, "problem" ) ); else #endif { if (exporterType.compare("none") == 0) exporter.reset( new ExporterEmpty<mesh_Type > ( dataFile, localMeshPtr, "problem", members ->comm->MyPID()) ); else exporter.reset( new ExporterEnsight<mesh_Type > ( dataFile, localMeshPtr, "problem", members->comm->MyPID()) ); } exporter->setPostDir( "./" ); // This is a test to see if M_post_dir is working exporter->setMeshProcId( localMeshPtr, members->comm->MyPID() ); vectorPtr_Type U ( new vector_Type(*problem.solution(), exporter->mapType() ) ); vectorPtr_Type V ( new vector_Type(*problem.solution(), exporter->mapType() ) ); vectorPtr_Type Exact ( new vector_Type(*problem.solution(), exporter->mapType() ) ); vectorPtr_Type vExact ( new vector_Type(*problem.solution(), exporter->mapType() ) ); vectorPtr_Type RHS ( new vector_Type(*problem.solution(), exporter->mapType() ) ); exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "displacement", feSpace, U, UInt(0) ); exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "velocity", feSpace, V, UInt(0) ); exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "uexact", feSpace, Exact, UInt(0) ); exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "vexact", feSpace, vExact, UInt(0) ); exporter->postProcess( 0 ); //initialization of unk //evaluate disp and vel as interpolate the bcFunction d0 and v0 feSpace->interpolate( static_cast<FESpace_type::function_Type>( d0 ), *U, 0.0 ); feSpace->interpolate( static_cast<FESpace_type::function_Type>( v0 ), *V, 0.0 ); //evaluate disp and vel as interpolate the bcFunction d0 and v0 std::vector<vectorPtr_Type> uv0; if (TimeAdvanceMethod =="Newmark") { uv0.push_back(U); uv0.push_back(V); } if (TimeAdvanceMethod =="BDF") { for ( UInt previousPass=0; previousPass < dataProblem->dataTimeAdvance()->orderBDF() ; previousPass++) { Real previousTimeStep = -previousPass*dt; // <<<<<<< HEAD feSpace->interpolate(uexact, *U, previousTimeStep ); uv0.push_back(U); // ======= // feSpace->interpolate( static_cast<FESpace_type::function_Type>( uexact ), *U, previousTimeStep ); // uv0.push_back(*U); //>>>>>>> master } } //the uv0[0] should be the displacement //the uv0[1] should be the velocity //timeAdvance->setInitialCondition(uv0[0],uv0[1]); timeAdvance->setInitialCondition(uv0); timeAdvance-> setTimeStep(dataProblem->dataTime()->timeStep()); timeAdvance->showMe(); feSpace->interpolate( static_cast<FESpace_type::function_Type>( uexact ), *Exact , 0); feSpace->interpolate( static_cast<FESpace_type::function_Type>( v0 ), *vExact , 0); *U = timeAdvance->solution(); *V = timeAdvance->firstDerivative(); for (Real time = dt; time <= T; time += dt) { dataProblem->dataTime()->setTime(time); if (verbose) { std::cout << std::endl; std::cout << " P - Now we are at time " << dataProblem->dataTime()->time() << " s." << std::endl; } //evaluate rhs rhs *=0; timeAdvance->updateRHSContribution(dt); rhsV = timeAdvance->rhsContributionFirstDerivative(); feSpace->l2ScalarProduct(source_in, rhs, time); rhs += problem.matrMass() *rhsV; //updateRHS problem.updateRHS(rhs); //solver system problem.iterate( bcH ); // Computes the matrices and solves the system //update unknowns of timeAdvance timeAdvance->shiftRight(*problem.solution()); //evaluate uexact solution feSpace->interpolate( static_cast<FESpace_type::function_Type>( uexact ), *Exact , time); feSpace->interpolate( static_cast<FESpace_type::function_Type>( v0 ), *vExact , time); *U = timeAdvance->solution(); *V =timeAdvance->firstDerivative(); //postProcess exporter->postProcess(time); // Error L2 and H1 Norms AnalyticalSol uExact; vector_Type u (*problem.solution(), Repeated); Real H1_Error, H1_RelError, L2_Error, L2_RelError; L2_Error = feSpace->l2Error(uexact, u, time ,&L2_RelError); H1_Error = feSpace->h1Error(uExact, u, time ,&H1_RelError); //save the norm if (verbose) { out_norm.open("norm.txt", std::ios::app); out_norm << time << " " << L2_Error << " " << H1_Error << " " << L2_RelError << " " << H1_RelError << "\n"; out_norm.close(); } MPI_Barrier(MPI_COMM_WORLD); } chrono.stop(); if (verbose) std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl; }
Int main ( Int argc, char** argv ) { //! Initializing Epetra communicator MPI_Init (&argc, &argv); boost::shared_ptr<Epetra_Comm> Comm ( new Epetra_MpiComm (MPI_COMM_WORLD) ); if ( Comm->MyPID() == 0 ) { std::cout << "% using MPI" << std::endl; } //********************************************// // Import parameters from an xml list. Use // // Teuchos to create a list from a given file // // in the execution directory. // //********************************************// std::cout << "Importing parameters list..."; Teuchos::ParameterList FHNParameterList = * ( Teuchos::getParametersFromXmlFile ( "FitzHughNagumoParameters.xml" ) ); std::cout << " Done!" << std::endl; //********************************************// // Creates a new model object representing the// // model from Fitz-Hugh Nagumo. The // // model input are the parameters. Pass the // // parameter list in the constructor // //********************************************// std::cout << "Building Constructor for Fitz-Hugh Nagumo Model with parameters ... "; IonicFitzHughNagumo model ( FHNParameterList ); std::cout << " Done!" << std::endl; //********************************************// // Show the parameters of the model as well as// // other informations about the object. // //********************************************// model.showMe(); //********************************************// // Simulation starts on t=0 and ends on t=TF. // // The timestep is given by dt // //********************************************// Real TF ( FHNParameterList.get ("TF", 300.0) ); Real dt ( FHNParameterList.get ("dt", 0.01) ); std::cout << "Time parameters : " << std::endl; std::cout << "TF = " << TF << std::endl; std::cout << "dt = " << dt << std::endl; std::string filename = "test_expeuler.txt"; std::ofstream output (filename.c_str() ); //********************************************// // Time loop starts. // //********************************************// std::cout << "Time loop starts...\n\n\n"; LifeChrono chrono; chrono.start(); Real valueToTest; valueToTest = EulerExplicit (dt, TF, model, FHNParameterList.get ("Iapp", 2000.0), output); chrono.stop(); std::cout << "\n...Time loop ends.\n"; std::cout << "\nElapsed time : " << chrono.diff() << std::endl; std::cout << "Solution written on file: " << filename << "\n"; //********************************************// // Close exported file. // //********************************************// output.close(); //! Finalizing Epetra communicator MPI_Finalize(); Real returnValue; Real err = std::abs (valueToTest - SolutionTestNorm) / std::abs (SolutionTestNorm); std::cout << std::setprecision (20) << "\nError: " << err << "\nSolution norm: " << valueToTest << "\n"; if ( err > 1e-12 ) { returnValue = EXIT_FAILURE; // Norm of solution did not match } else { returnValue = EXIT_SUCCESS; } return ( returnValue ); }
void Cylinder::run() { typedef FESpace< mesh_Type, MapEpetra > feSpace_Type; typedef boost::shared_ptr<feSpace_Type> feSpacePtr_Type; typedef OseenSolver< mesh_Type >::vector_Type vector_Type; typedef boost::shared_ptr<vector_Type> vectorPtr_Type; // Reading from data file // GetPot dataFile( d->data_file_name ); // int save = dataFile("fluid/miscellaneous/save", 1); bool verbose = (d->comm->MyPID() == 0); // Boundary conditions BCHandler bcH; BCFunctionBase uZero( zero_scalar ); std::vector<ID> zComp(1); zComp[0] = 3; BCFunctionBase uIn ( d->getU_2d() ); BCFunctionBase uOne ( d->getU_one() ); BCFunctionBase uPois( d->getU_pois() ); //BCFunctionBase unormal( d->get_normal() ); //cylinder bcH.addBC( "Inlet", INLET, Essential, Full, uPois , 3 ); bcH.addBC( "Ringin", RINGIN, Essential, Full, uZero , 3 ); bcH.addBC( "Ringout", RINGOUT, Essential, Full, uZero , 3 ); bcH.addBC( "Outlet", OUTLET, Natural, Full, uZero, 3 ); bcH.addBC( "Wall", WALL, Essential, Full, uZero, 3 ); int numLM = 0; boost::shared_ptr<OseenData> oseenData(new OseenData()); oseenData->setup( dataFile ); MeshData meshData; meshData.setup(dataFile, "fluid/space_discretization"); boost::shared_ptr<mesh_Type> fullMeshPtr ( new mesh_Type( d->comm ) ); readMesh(*fullMeshPtr, meshData); boost::shared_ptr<mesh_Type> meshPtr; { MeshPartitioner< mesh_Type > meshPart(fullMeshPtr, d->comm); meshPtr = meshPart.meshPartition(); } if (verbose) std::cout << std::endl; if (verbose) std::cout << "Time discretization order " << oseenData->dataTime()->orderBDF() << std::endl; //oseenData.meshData()->setMesh(meshPtr); std::string uOrder = dataFile( "fluid/space_discretization/vel_order", "P1"); if (verbose) std::cout << "Building the velocity FE space ... " << std::flush; feSpacePtr_Type uFESpacePtr( new feSpace_Type(meshPtr,uOrder,3,d->comm) ); if (verbose) std::cout << "ok." << std::endl; std::string pOrder = dataFile( "fluid/space_discretization/press_order", "P1"); if (verbose) std::cout << "Building the pressure FE space ... " << std::flush; feSpacePtr_Type pFESpacePtr( new feSpace_Type(meshPtr,pOrder,1,d->comm) ); if (verbose) std::cout << "ok." << std::endl; UInt totalVelDof = uFESpacePtr->map().map(Unique)->NumGlobalElements(); UInt totalPressDof = pFESpacePtr->map().map(Unique)->NumGlobalElements(); if (verbose) std::cout << "Total Velocity DOF = " << totalVelDof << std::endl; if (verbose) std::cout << "Total Pressure DOF = " << totalPressDof << std::endl; if (verbose) std::cout << "Calling the fluid constructor ... "; bcH.setOffset( "Inlet", totalVelDof + totalPressDof - 1 ); OseenSolver< mesh_Type > fluid (oseenData, *uFESpacePtr, *pFESpacePtr, d->comm, numLM); MapEpetra fullMap(fluid.getMap()); if (verbose) std::cout << "ok." << std::endl; fluid.setUp(dataFile); fluid.buildSystem(); MPI_Barrier(MPI_COMM_WORLD); // Initialization Real dt = oseenData->dataTime()->timeStep(); Real t0 = oseenData->dataTime()->initialTime(); Real tFinal = oseenData->dataTime()->endTime(); // bdf object to store the previous solutions TimeAdvanceBDFNavierStokes<vector_Type> bdf; bdf.setup(oseenData->dataTime()->orderBDF()); vector_Type beta( fullMap ); vector_Type rhs ( fullMap ); #ifdef HAVE_HDF5 ExporterHDF5<mesh_Type > ensight( dataFile, meshPtr, "cylinder", d->comm->MyPID()); #else ExporterEnsight<mesh_Type > ensight( dataFile, meshPtr, "cylinder", d->comm->MyPID()); #endif vectorPtr_Type velAndPressure ( new vector_Type(*fluid.solution(), ensight.mapType() ) ); ensight.addVariable( ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr, velAndPressure, UInt(0) ); ensight.addVariable( ExporterData<mesh_Type>::ScalarField, "pressure", pFESpacePtr, velAndPressure, UInt(3*uFESpacePtr->dof().numTotalDof() ) ); // initialization with stokes solution if (d->initial_sol == "stokes") { if (verbose) std::cout << std::endl; if (verbose) std::cout << "Computing the stokes solution ... " << std::endl << std::endl; oseenData->dataTime()->setTime(t0); MPI_Barrier(MPI_COMM_WORLD); beta *= 0.; rhs *= 0.; fluid.updateSystem(0, beta, rhs ); fluid.iterate( bcH ); // fluid.postProcess(); *velAndPressure = *fluid.solution(); ensight.postProcess( 0 ); fluid.resetPreconditioner(); } bdf.bdfVelocity().setInitialCondition( *fluid.solution() ); // Temporal loop LifeChrono chrono; int iter = 1; for ( Real time = t0 + dt ; time <= tFinal + dt/2.; time += dt, iter++) { oseenData->dataTime()->setTime(time); if (verbose) { std::cout << std::endl; std::cout << "We are now at time "<< oseenData->dataTime()->time() << " s. " << std::endl; std::cout << std::endl; } chrono.start(); double alpha = bdf.bdfVelocity().coefficientFirstDerivative( 0 ) / oseenData->dataTime()->timeStep(); beta = bdf.bdfVelocity().extrapolation(); bdf.bdfVelocity().updateRHSContribution( oseenData->dataTime()->timeStep()); rhs = fluid.matrixMass()*bdf.bdfVelocity().rhsContributionFirstDerivative(); fluid.updateSystem( alpha, beta, rhs ); fluid.iterate( bcH ); bdf.bdfVelocity().shiftRight( *fluid.solution() ); // if (((iter % save == 0) || (iter == 1 ))) // { *velAndPressure = *fluid.solution(); ensight.postProcess( time ); // } // postProcessFluxesPressures(fluid, bcH, time, verbose); MPI_Barrier(MPI_COMM_WORLD); chrono.stop(); if (verbose) std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl; } }
// =================================================== //! Methods // =================================================== void test_bdf::run() { //Useful typedef typedef SolverAztecOO solver_type; typedef VectorEpetra vector_type; typedef boost::shared_ptr<vector_type> vector_ptrtype; // Reading from data file GetPot dataFile(Members->data_file_name.c_str()); // Select Pid(0) to write on std output bool verbose = (Members->comm->MyPID() == 0); if (verbose) std::cout << "The BDF Solver" << std::flush; //the forcing term SourceFct sf; // the boundary conditions BCFunctionBase g_Ess(AnalyticalSol::u); BCHandler bc; bc.addBC("Top", TOP, Essential, Full, g_Ess, 1); bc.addBC("Bottom", BOTTOM, Essential, Full, g_Ess, 1); bc.addBC("Left", LEFT, Essential, Full, g_Ess, 1); bc.addBC("Right", RIGHT, Essential, Full, g_Ess, 1); bc.addBC("Front", FRONT, Essential, Full, g_Ess, 1); bc.addBC("Back", BACK, Essential, Full, g_Ess, 1); //============================================================================= //Mesh stuff Members->comm->Barrier(); MeshData meshData(dataFile, ("bdf/" + discretization_section).c_str()); boost::shared_ptr<regionMesh> fullMeshPtr( new regionMesh( Members->comm ) ); readMesh(*fullMeshPtr,meshData); boost::shared_ptr<regionMesh> meshPtr; { MeshPartitioner<regionMesh> meshPart( fullMeshPtr, Members->comm ); meshPtr = meshPart.meshPartition(); } //============================================================================= //finite element space of the solution boost::shared_ptr<FESpace<regionMesh, MapEpetra> > feSpacePtr( new FESpace<regionMesh, MapEpetra> ( meshPtr, dataFile(("bdf/"+discretization_section + "/order").c_str(), "P2"), 1, Members->comm) ); if (verbose) std::cout << " Number of unknowns : " << feSpacePtr->map().map(Unique)->NumGlobalElements() << std::endl; bc.bcUpdate(*(feSpacePtr->mesh()), feSpacePtr->feBd(), feSpacePtr->dof()); //============================================================================= //Fe Matrices and vectors MatrixElemental elmat(feSpacePtr->fe().nbFEDof(), 1, 1); //local matrix MatrixEpetra<double> matM(feSpacePtr->map()); //mass matrix boost::shared_ptr<MatrixEpetra<double> > matA_ptr( new MatrixEpetra<double> (feSpacePtr->map())); //stiff matrix VectorEpetra u(feSpacePtr->map(), Unique); // solution vector VectorEpetra f(feSpacePtr->map(), Unique); // forcing term vector LifeChrono chrono; //Assembling Matrix M Members->comm->Barrier(); chrono.start(); for (UInt iVol = 0; iVol < feSpacePtr->mesh()->numElements(); iVol++) { feSpacePtr->fe().updateJac(feSpacePtr->mesh()->element(iVol)); elmat.zero(); mass(1., elmat, feSpacePtr->fe(), 0, 0); assembleMatrix(matM, elmat, feSpacePtr->fe(), feSpacePtr->fe(), feSpacePtr->dof(), feSpacePtr->dof(), 0, 0, 0, 0); } matM.globalAssemble(); Members->comm->Barrier(); chrono.stop(); if (verbose) std::cout << "\n \n -- Mass matrix assembling time = " << chrono.diff() << std::endl << std::endl; // ========================================== // Definition of the time integration stuff // ========================================== Real Tfin = dataFile("bdf/endtime", 10.0); Real delta_t = dataFile("bdf/timestep", 0.5); Real t0 = 1.; UInt ord_bdf = dataFile("bdf/order", 3); TimeAdvanceBDFVariableStep<VectorEpetra> bdf; bdf.setup(ord_bdf); //Initialization bdf.setInitialCondition<Real(*) (Real, Real, Real, Real, UInt), FESpace<regionMesh, MapEpetra> >(AnalyticalSol::u, u, *feSpacePtr, t0, delta_t); if (verbose) bdf.showMe(); Members->comm->Barrier(); //=================================================== // post processing setup boost::shared_ptr<Exporter<regionMesh> > exporter; std::string const exporterType = dataFile( "exporter/type", "hdf5"); #ifdef HAVE_HDF5 if (exporterType.compare("hdf5") == 0) { exporter.reset( new ExporterHDF5<regionMesh > ( dataFile, "bdf_test" ) ); } else #endif { if (exporterType.compare("none") == 0) { exporter.reset( new ExporterEmpty<regionMesh > ( dataFile, meshPtr, "bdf_test", Members->comm->MyPID()) ); } else { exporter.reset( new ExporterEnsight<regionMesh > ( dataFile, meshPtr, "bdf_test", Members->comm->MyPID()) ); } } exporter->setPostDir( "./" ); exporter->setMeshProcId( meshPtr, Members->comm->MyPID() ); boost::shared_ptr<VectorEpetra> u_display_ptr(new VectorEpetra( feSpacePtr->map(), exporter->mapType())); exporter->addVariable(ExporterData<regionMesh >::ScalarField, "u", feSpacePtr, u_display_ptr, UInt(0)); *u_display_ptr = u; exporter->postProcess(0); //=================================================== //Definition of the linear solver SolverAztecOO az_A(Members->comm); az_A.setDataFromGetPot(dataFile, "bdf/solver"); az_A.setupPreconditioner(dataFile, "bdf/prec"); //=================================================== // TIME LOOP //=================================================== matA_ptr.reset(new MatrixEpetra<double> (feSpacePtr->map())); for (Real t = t0 + delta_t; t <= Tfin; t += delta_t) { Members->comm->Barrier(); if (verbose) cout << "Now we are at time " << t << endl; chrono.start(); //Assemble A Real coeff = bdf.coefficientDerivative(0) / delta_t; Real visc = nu(t); Real s = sigma(t); for (UInt i = 0; i < feSpacePtr->mesh()->numElements(); i++) { feSpacePtr->fe().updateFirstDerivQuadPt(feSpacePtr->mesh()->element(i)); elmat.zero(); mass(coeff + s, elmat, feSpacePtr->fe()); stiff(visc, elmat, feSpacePtr->fe()); assembleMatrix(*matA_ptr, elmat, feSpacePtr->fe(), feSpacePtr->fe(), feSpacePtr->dof(), feSpacePtr->dof(), 0, 0, 0, 0); } chrono.stop(); if (verbose) cout << "A has been constructed in "<< chrono.diff() << "s." << endl; // Handling of the right hand side f = (matM*bdf.rhsContribution()); //f = M*\sum_{i=1}^{orderBdf} \alpha_i u_{n-i} feSpacePtr->l2ScalarProduct(sf, f, t); //f +=\int_\Omega{ volumeForces *v dV} Members->comm->Barrier(); // Treatment of the Boundary conditions if (verbose) cout << "*** BC Management: " << endl; Real tgv = 1.; chrono.start(); bcManage(*matA_ptr, f, *feSpacePtr->mesh(), feSpacePtr->dof(), bc, feSpacePtr->feBd(), tgv, t); matA_ptr->globalAssemble(); chrono.stop(); if (verbose) cout << chrono.diff() << "s." << endl; //Set Up the linear system Members->comm->Barrier(); chrono.start(); az_A.setMatrix(*matA_ptr); az_A.setReusePreconditioner(false); Members->comm->Barrier(); az_A.solveSystem(f, u, matA_ptr); chrono.stop(); bdf.shiftRight(u); if (verbose) cout << "*** Solution computed in " << chrono.diff() << "s." << endl; Members->comm->Barrier(); // Error in the L2 vector_type uComputed(u, Repeated); Real L2_Error, L2_RelError; L2_Error = feSpacePtr->l2Error(AnalyticalSol::u, uComputed, t, &L2_RelError); if (verbose) std::cout << "Error Norm L2: " << L2_Error << "\nRelative Error Norm L2: " << L2_RelError << std::endl; Members->errorNorm = L2_Error; //transfer the solution at time t. *u_display_ptr = u; matA_ptr->zero(); exporter->postProcess(t); } }
void EnsightToHdf5::run() { // Reading from data file GetPot dataFile ( d->data_file_name.c_str() ); bool verbose = (d->comm->MyPID() == 0); // Fluid solver boost::shared_ptr<OseenData> oseenData (new OseenData() ); oseenData->setup ( dataFile ); MeshData meshData; meshData.setup (dataFile, "fluid/space_discretization"); boost::shared_ptr<mesh_Type > fullMeshPtr (new mesh_Type ( d->comm ) ); readMesh (*fullMeshPtr, meshData); // writeMesh("test.mesh", *fullMeshPtr); // Scale, Rotate, Translate (if necessary) boost::array< Real, NDIM > geometryScale; boost::array< Real, NDIM > geometryRotate; boost::array< Real, NDIM > geometryTranslate; geometryScale[0] = dataFile ( "fluid/space_discretization/transform", 1., 0); geometryScale[1] = dataFile ( "fluid/space_discretization/transform", 1., 1); geometryScale[2] = dataFile ( "fluid/space_discretization/transform", 1., 2); geometryRotate[0] = dataFile ( "fluid/space_discretization/transform", 0., 3) * M_PI / 180; geometryRotate[1] = dataFile ( "fluid/space_discretization/transform", 0., 4) * M_PI / 180; geometryRotate[2] = dataFile ( "fluid/space_discretization/transform", 0., 5) * M_PI / 180; geometryTranslate[0] = dataFile ( "fluid/space_discretization/transform", 0., 6); geometryTranslate[1] = dataFile ( "fluid/space_discretization/transform", 0., 7); geometryTranslate[2] = dataFile ( "fluid/space_discretization/transform", 0., 8); MeshUtility::MeshTransformer<mesh_Type, mesh_Type::markerCommon_Type > _transformMesh (*fullMeshPtr); _transformMesh.transformMesh ( geometryScale, geometryRotate, geometryTranslate ); boost::shared_ptr<mesh_Type > meshPtr; { MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, d->comm); meshPtr = meshPart.meshPartition(); } std::string uOrder = dataFile ( "fluid/space_discretization/vel_order", "P1"); std::string pOrder = dataFile ( "fluid/space_discretization/press_order", "P1"); //oseenData->meshData()->setMesh(meshPtr); if (verbose) { std::cout << "Building the velocity FE space ... " << std::flush; } feSpacePtr_Type uFESpacePtr ( new feSpace_Type (meshPtr, uOrder, 3, d->comm) ); if (verbose) { std::cout << "ok." << std::endl; } if (verbose) { std::cout << "Building the pressure FE space ... " << std::flush; } feSpacePtr_Type pFESpacePtr ( new feSpace_Type ( meshPtr, pOrder, 1, d->comm ) ); if (verbose) { std::cout << "ok." << std::endl; } if (verbose) { std::cout << "Building the P0 pressure FE space ... " << std::flush; } feSpacePtr_Type p0FESpacePtr ( new feSpace_Type ( meshPtr, feTetraP0, quadRuleTetra1pt, quadRuleTria1pt, 1, d->comm ) ); if (verbose) { std::cout << "ok." << std::endl; } UInt totalVelDof = uFESpacePtr->map().map (Unique)->NumGlobalElements(); UInt totalPressDof = pFESpacePtr->map().map (Unique)->NumGlobalElements(); UInt totalP0PresDof = p0FESpacePtr->map().map (Unique)->NumGlobalElements(); if (verbose) { std::cout << "Total Velocity DOF = " << totalVelDof << std::endl; } if (verbose) { std::cout << "Total Pressure DOF = " << totalPressDof << std::endl; } if (verbose) { std::cout << "Total P0Press DOF = " << totalP0PresDof << std::endl; } if (verbose) { std::cout << "Calling the fluid constructor ... "; } OseenSolver< mesh_Type > fluid (oseenData, *uFESpacePtr, *pFESpacePtr, d->comm); MapEpetra fullMap (fluid.getMap() ); if (verbose) { std::cout << "ok." << std::endl; } fluid.setUp (dataFile); // Initialization Real dt = oseenData->dataTime()->timeStep(); Real t0 = oseenData->dataTime()->initialTime(); Real tFinal = oseenData->dataTime()->endTime(); boost::shared_ptr< Exporter<mesh_Type > > exporter; boost::shared_ptr< Exporter<mesh_Type > > importer; std::string const exporterType = dataFile ( "exporter/type", "hdf5"); std::string const exporterName = dataFile ( "exporter/filename", "ethiersteinman"); std::string const exportDir = dataFile ( "exporter/exportDir", "./"); std::string const importerType = dataFile ( "importer/type", "ensight"); std::string const importerName = dataFile ( "importer/filename", "ethiersteinman"); std::string const importDir = dataFile ( "importer/importDir", "importDir/"); #ifdef HAVE_HDF5 if (exporterType.compare ("hdf5") == 0) { exporter.reset ( new ExporterHDF5<mesh_Type > ( dataFile, exporterName ) ); } else #endif exporter.reset ( new ExporterEnsight<mesh_Type > ( dataFile, exporterName ) ); exporter->setPostDir ( exportDir ); // This is a test to see if M_post_dir is working exporter->setMeshProcId ( meshPtr, d->comm->MyPID() ); #ifdef HAVE_HDF5 if (importerType.compare ("hdf5") == 0) { importer.reset ( new ExporterHDF5<mesh_Type > ( dataFile, importerName ) ); } else #endif importer.reset ( new ExporterEnsight<mesh_Type > ( dataFile, importerName ) ); // todo this will not work with the ExporterEnsight filter (it uses M_importDir, a private variable) importer->setPostDir ( importDir ); // This is a test to see if M_post_dir is working importer->setMeshProcId ( meshPtr, d->comm->MyPID() ); vectorPtr_Type velAndPressureExport ( new vector_Type (*fluid.solution(), exporter->mapType() ) ); vectorPtr_Type velAndPressureImport ( new vector_Type (*fluid.solution(), importer->mapType() ) ); if ( exporter->mapType() == Unique ) { velAndPressureExport->setCombineMode (Zero); } importer->addVariable ( ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr, velAndPressureImport, UInt (0) ); importer->addVariable ( ExporterData<mesh_Type>::ScalarField, "pressure", pFESpacePtr, velAndPressureImport, UInt (3 * uFESpacePtr->dof().numTotalDof() ) ); importer->import ( t0 ); *velAndPressureExport = *velAndPressureImport; vectorPtr_Type P0pres ( new vector_Type (p0FESpacePtr->map() ) ); MPI_Barrier (MPI_COMM_WORLD); computeP0pressure (pFESpacePtr, p0FESpacePtr, uFESpacePtr, *velAndPressureImport, *P0pres, t0); exporter->addVariable ( ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr, velAndPressureExport, UInt (0) ); exporter->addVariable ( ExporterData<mesh_Type>::ScalarField, "pressure", pFESpacePtr, velAndPressureExport, UInt (3 * uFESpacePtr->dof().numTotalDof() ) ); exporter->addVariable (ExporterData<mesh_Type>::ScalarField, "P0pressure", p0FESpacePtr, P0pres, UInt (0), ExporterData<mesh_Type>::SteadyRegime, ExporterData<mesh_Type>::Cell ); exporter->postProcess ( t0 ); // Temporal loop LifeChrono chrono; int iter = 1; for ( Real time = t0 + dt ; time <= tFinal + dt / 2.; time += dt, iter++) { chrono.stop(); importer->import ( time ); *velAndPressureExport = *velAndPressureImport; MPI_Barrier (MPI_COMM_WORLD); computeP0pressure (pFESpacePtr, p0FESpacePtr, uFESpacePtr, *velAndPressureImport, *P0pres, time); exporter->postProcess ( time ); chrono.stop(); if (verbose) { std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl; } } }
void Heart::computeRhs ( vector_Type& rhs, HeartMonodomainSolver< mesh_Type >& electricModel, boost::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel, HeartMonodomainData& data ) { bool verbose = (M_heart_fct->M_comm->MyPID() == 0); if (verbose) { std::cout << " f- Computing Rhs ... " << "\n" << std::flush; } LifeChrono chrono; chrono.start(); //! u, w with repeated map vector_Type uVecRep (electricModel.solutionTransmembranePotential(), Repeated); ionicModel->updateRepeated(); VectorElemental elvec_Iapp ( electricModel.potentialFESpace().fe().nbFEDof(), 2 ), elvec_u ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ), elvec_Iion ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ); for (UInt iVol = 0; iVol < electricModel.potentialFESpace().mesh()->numVolumes(); ++iVol) { electricModel.potentialFESpace().fe().updateJacQuadPt ( electricModel.potentialFESpace().mesh()->volumeList ( iVol ) ); elvec_Iapp.zero(); elvec_u.zero(); elvec_Iion.zero(); UInt eleIDu = electricModel.potentialFESpace().fe().currentLocalId(); UInt nbNode = ( UInt ) electricModel.potentialFESpace().fe().nbFEDof(); //! Filling local elvec_u with potential values in the nodes for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ ) { Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode ); elvec_u.vec() [ iNode ] = uVecRep[ig]; } ionicModel->updateElementSolution (eleIDu); ionicModel->computeIonicCurrent (data.membraneCapacitance(), elvec_Iion, elvec_u, electricModel.potentialFESpace() ); //! Computing the current source of the righthand side, repeated AssemblyElemental::source (M_heart_fct->stimulus(), elvec_Iapp, electricModel.potentialFESpace().fe(), data.time(), 0); AssemblyElemental::source (M_heart_fct->stimulus(), elvec_Iapp, electricModel.potentialFESpace().fe(), data.time(), 1); //! Assembling the righthand side for ( UInt i = 0 ; i < electricModel.potentialFESpace().fe().nbFEDof() ; i++ ) { Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, i ); rhs.sumIntoGlobalValues (ig, (data.conductivityRatio() * elvec_Iapp.vec() [i] + elvec_Iapp.vec() [i + nbNode]) / (1 + data.conductivityRatio() ) + data.volumeSurfaceRatio() * elvec_Iion.vec() [i] ); } } rhs.globalAssemble(); Real coeff = data.volumeSurfaceRatio() * data.membraneCapacitance() / data.timeStep(); vector_Type tmpvec (electricModel.solutionTransmembranePotential() ); tmpvec *= coeff; rhs += electricModel.massMatrix() * tmpvec; MPI_Barrier (MPI_COMM_WORLD); chrono.stop(); if (verbose) { std::cout << "done in " << chrono.diff() << " s." << std::endl; } }
// =================================================== // Methods // =================================================== Int LinearSolver::solve ( vectorPtr_Type solutionPtr ) { // Build preconditioners if needed bool retry ( true ); if ( !isPreconditionerSet() || !M_reusePreconditioner ) { buildPreconditioner(); // There will be no retry if the preconditioner is recomputed retry = false; } else { if ( !M_silent ) { M_displayer->leaderPrint ( "SLV- Reusing precond ...\n" ); } } if ( M_rhs.get() == 0 || M_operator == 0 ) { M_displayer->leaderPrint ( "SLV- ERROR: LinearSolver failed to set up correctly!\n" ); return -1; } // Setup the Solver Operator setupSolverOperator(); // Reset status informations bool failure = false; this->resetStatus(); M_solverOperator->resetStatus(); // Solve the linear system LifeChrono chrono; chrono.start(); M_solverOperator->ApplyInverse ( M_rhs->epetraVector(), solutionPtr->epetraVector() ); M_converged = M_solverOperator->hasConverged(); M_lossOfPrecision = M_solverOperator->isLossOfAccuracyDetected(); chrono.stop(); if ( !M_silent ) { M_displayer->leaderPrintMax ( "SLV- Solution time: " , chrono.diff(), " s." ); } // Getting informations post-solve Int numIters = M_solverOperator->numIterations(); // Second run recomputing the preconditioner // This is done only if the preconditioner has not been // already recomputed and if it is a LifeV preconditioner. if ( M_converged != SolverOperator_Type::yes && retry && M_preconditioner ) { M_displayer->leaderPrint ( "SLV- Iterative solver failed, numiter = " , numIters, "\n" ); M_displayer->leaderPrint ( "SLV- retrying:\n" ); buildPreconditioner(); // Solving again, but only once (retry = false) chrono.start(); M_solverOperator->ApplyInverse ( M_rhs->epetraVector(), solutionPtr->epetraVector() ); M_converged = M_solverOperator->hasConverged(); M_lossOfPrecision = M_solverOperator->isLossOfAccuracyDetected(); chrono.stop(); if ( !M_silent ) { M_displayer->leaderPrintMax ( "SLV- Solution time: " , chrono.diff(), " s." ); } } if ( M_lossOfPrecision == SolverOperator_Type::yes ) { M_displayer->leaderPrint ( "SLV- WARNING: Loss of accuracy detected!\n" ); failure = true; } if ( M_converged == SolverOperator_Type::yes ) { if ( !M_silent ) { M_displayer->leaderPrint ( "SLV- Convergence in " , numIters, " iterations\n" ); } M_maxNumItersReached = SolverOperator_Type::no; } else { M_displayer->leaderPrint ( "SLV- WARNING: Solver failed to converged to the desired precision!\n" ); M_maxNumItersReached = SolverOperator_Type::yes; failure = true; } // If quitOnFailure is enabled and if some problems occur // the simulation is stopped if ( M_quitOnFailure && failure ) { exit ( -1 ); } // Reset the solver to free the internal pointers M_solverOperator->resetSolver(); // If the number of iterations reaches the threshold of maxIterForReuse // we reset the preconditioners to force to solver to recompute it next // time if ( numIters > M_maxItersForReuse ) { resetPreconditioner(); } return numIters; }
void Heart::run() { typedef FESpace< mesh_Type, MapEpetra > feSpace_Type; typedef boost::shared_ptr<feSpace_Type> feSpacePtr_Type; LifeChrono chronoinitialsettings; LifeChrono chronototaliterations; chronoinitialsettings.start(); Real normu; Real meanu; Real minu; //! Construction of data classes #ifdef MONODOMAIN HeartMonodomainData _data (M_heart_fct); #else HeartBidomainData _data (M_heart_fct); #endif HeartIonicData _dataIonic (M_heart_fct->M_dataFile); MeshData meshData; meshData.setup (M_heart_fct->M_dataFile, "electric/space_discretization"); boost::shared_ptr<mesh_Type > fullMeshPtr ( new mesh_Type ( M_heart_fct->M_comm ) ); readMesh (*fullMeshPtr, meshData); bool verbose = (M_heart_fct->M_comm->MyPID() == 0); //! Boundary conditions handler and function BCFunctionBase uZero ( zero_scalar ); BCHandler bcH; bcH.addBC ( "Endo", ENDOCARDIUM, Natural, Full, uZero, 1 ); bcH.addBC ( "Epi", EPICARDIUM, Natural, Full, uZero, 1 ); bcH.addBC ( "Trunc", TRUNC_SEC, Natural, Full, uZero, 1 ); const ReferenceFE* refFE_w; const QuadratureRule* qR_w; const QuadratureRule* bdQr_w; const ReferenceFE* refFE_u; const QuadratureRule* qR_u; const QuadratureRule* bdQr_u; //! Construction of the partitioned mesh boost::shared_ptr<mesh_Type> localMeshPtr; { MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, M_heart_fct->M_comm); localMeshPtr = meshPart.meshPartition(); } std::string uOrder = M_heart_fct->M_dataFile ( "electric/space_discretization/u_order", "P1"); //! Initialization of the FE type and quadrature rules for both the variables if ( uOrder.compare ("P1") == 0 ) { if (verbose) { std::cout << "P1 potential " << std::flush; } refFE_u = &feTetraP1; qR_u = &quadRuleTetra15pt; bdQr_u = &quadRuleTria3pt; } else { cout << "\n " << uOrder << " finite element not implemented yet \n"; exit (1); } std::string wOrder = M_heart_fct->M_dataFile ( "electric/space_discretization/w_order", "P1"); if ( wOrder.compare ("P1") == 0 ) { if (verbose) { std::cout << "P1 recovery variable " << std::flush; } refFE_w = &feTetraP1; qR_w = &quadRuleTetra4pt; bdQr_w = &quadRuleTria3pt; } else { cout << "\n " << wOrder << " finite element not implemented yet \n"; exit (1); } //! Construction of the FE spaces if (verbose) { std::cout << "Building the potential FE space ... " << std::flush; } feSpacePtr_Type uFESpacePtr ( new feSpace_Type ( localMeshPtr, *refFE_u, *qR_u, *bdQr_u, 1, M_heart_fct->M_comm) ); #ifdef BIDOMAIN feSpacePtr_Type _FESpacePtr ( new feSpace_Type (localMeshPtr, *refFE_u, *qR_u, *bdQr_u, 2, M_heart_fct->M_comm) ); #endif if (verbose) { std::cout << "ok." << std::endl; } if (verbose) { std::cout << "Building the recovery variable FE space ... " << std::flush; } if (verbose) { std::cout << "ok." << std::endl; } UInt totalUDof = uFESpacePtr->map().map (Unique)->NumGlobalElements(); if (verbose) { std::cout << "Total Potential DOF = " << totalUDof << std::endl; } if (verbose) { std::cout << "Calling the electric model constructor ... "; } #ifdef MONODOMAIN HeartMonodomainSolver< mesh_Type > electricModel (_data, *uFESpacePtr, bcH, M_heart_fct->M_comm); #else HeartBidomainSolver< mesh_Type > electricModel (_data, *_FESpacePtr, *uFESpacePtr, bcH, M_heart_fct->M_comm); #endif if (verbose) { std::cout << "ok." << std::endl; } MapEpetra fullMap (electricModel.getMap() ); vector_Type rhs ( fullMap); electricModel.setup ( M_heart_fct->M_dataFile ); std::cout << "setup ok" << std::endl; if (verbose) { std::cout << "Calling the ionic model constructor ... "; } boost::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel; if (ion_model == 1) { if (verbose) { std::cout << "Ion Model = Rogers-McCulloch" << std::endl << std::flush; } ionicModel.reset (new RogersMcCulloch< mesh_Type > (_dataIonic, *localMeshPtr, *uFESpacePtr, *M_heart_fct->M_comm) ); } else if (ion_model == 2) { if (verbose) { std::cout << "Ion Model = Luo-Rudy" << std::endl << std::flush; } ionicModel.reset (new LuoRudy< mesh_Type > (_dataIonic, *localMeshPtr, *uFESpacePtr, *M_heart_fct->M_comm) ); } else if (ion_model == 3) { if (verbose) { std::cout << "Ion Model = Mitchell-Schaeffer" << std::endl << std::flush; } ionicModel.reset (new MitchellSchaeffer< mesh_Type > (_dataIonic, *localMeshPtr, *uFESpacePtr, *M_heart_fct->M_comm) ); } #ifdef MONODOMAIN electricModel.initialize ( M_heart_fct->initialScalar() ); #else electricModel.initialize ( M_heart_fct->initialScalar(), M_heart_fct->zeroScalar() ); #endif if (verbose) { std::cout << "ok." << std::endl; } ionicModel->initialize( ); //! Building time-independent part of the system electricModel.buildSystem( ); std::cout << "buildsystem ok" << std::endl; //! Initialization Real dt = _data.timeStep(); Real t0 = 0; Real tFinal = _data.endTime(); MPI_Barrier (MPI_COMM_WORLD); if (verbose) { std::cout << "Setting the initial solution ... " << std::endl << std::endl; } _data.setTime (t0); electricModel.resetPreconditioner(); if (verbose) { std::cout << " ok " << std::endl; } //! Setting generic Exporter postprocessing boost::shared_ptr< Exporter<mesh_Type > > exporter; std::string const exporterType = M_heart_fct->M_dataFile ( "exporter/type", "ensight"); #ifdef HAVE_HDF5 if (exporterType.compare ("hdf5") == 0) { exporter.reset ( new ExporterHDF5<mesh_Type > ( M_heart_fct->M_dataFile, "heart" ) ); exporter->setPostDir ( "./" ); // This is a test to see if M_post_dir is working exporter->setMeshProcId ( localMeshPtr, M_heart_fct->M_comm->MyPID() ); } else #endif { if (exporterType.compare ("none") == 0) { exporter.reset ( new ExporterEmpty<mesh_Type > ( M_heart_fct->M_dataFile, localMeshPtr, "heart", M_heart_fct->M_comm->MyPID() ) ); } else { exporter.reset ( new ExporterEnsight<mesh_Type > ( M_heart_fct->M_dataFile, localMeshPtr, "heart", M_heart_fct->M_comm->MyPID() ) ); } } vectorPtr_Type Uptr ( new vector_Type (electricModel.solutionTransmembranePotential(), Repeated ) ); exporter->addVariable ( ExporterData<mesh_Type>::ScalarField, "potential", uFESpacePtr, Uptr, UInt (0) ); #ifdef BIDOMAIN vectorPtr_Type Ueptr ( new vector_Type (electricModel.solutionExtraPotential(), Repeated ) ); exporter->addVariable ( ExporterData<mesh_Type>::ScalarField, "potential_e", _FESpacePtr, Ueptr, UInt (0) ); #endif vectorPtr_Type Fptr ( new vector_Type (electricModel.fiberVector(), Repeated ) ); if (_data.hasFibers() ) exporter->addVariable ( ExporterData<mesh_Type>::VectorField, "fibers", uFESpacePtr, Fptr, UInt (0) ); exporter->postProcess ( 0 ); MPI_Barrier (MPI_COMM_WORLD); chronoinitialsettings.stop(); //! Temporal loop LifeChrono chrono; Int iter = 1; chronototaliterations.start(); for ( Real time = t0 + dt ; time <= tFinal + dt / 2.; time += dt, iter++) { _data.setTime (time); if (verbose) { std::cout << std::endl; std::cout << "We are now at time " << _data.time() << " s. " << std::endl; std::cout << std::endl; } chrono.start(); MPI_Barrier (MPI_COMM_WORLD); ionicModel->solveIonicModel ( electricModel.solutionTransmembranePotential(), _data.timeStep() ); rhs *= 0; computeRhs ( rhs, electricModel, ionicModel, _data ); electricModel.updatePDESystem ( rhs ); electricModel.PDEiterate ( bcH ); normu = electricModel.solutionTransmembranePotential().norm2(); electricModel.solutionTransmembranePotential().epetraVector().MeanValue (&meanu); electricModel.solutionTransmembranePotential().epetraVector().MaxValue (&minu); if (verbose) { std::cout << "norm u " << normu << std::endl; std::cout << "mean u " << meanu << std::endl; std::cout << "max u " << minu << std::endl << std::flush; } *Uptr = electricModel.solutionTransmembranePotential(); #ifdef BIDOMAIN *Ueptr = electricModel.solutionExtraPotential(); #endif exporter->postProcess ( time ); MPI_Barrier (MPI_COMM_WORLD); chrono.stop(); if (verbose) { std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl; } chronototaliterations.stop(); } if (verbose) { std::cout << "Total iterations time " << chronototaliterations.diff() << " s." << std::endl; } if (verbose) { std::cout << "Total initial settings time " << chronoinitialsettings.diff() << " s." << std::endl; } if (verbose) { std::cout << "Total execution time " << chronoinitialsettings.diff() + chronototaliterations.diff() << " s." << std::endl; } }
Int main ( Int argc, char** argv ) { //Setup main communicator boost::shared_ptr< Epetra_Comm > comm; //Setup MPI variables Int numberOfProcesses (1); Int rank (0); #ifdef HAVE_MPI MPI_Init ( &argc, &argv ); MPI_Comm_size ( MPI_COMM_WORLD, &numberOfProcesses ); MPI_Comm_rank ( MPI_COMM_WORLD, &rank ); #endif if ( rank == 0 ) { std::cout << std::endl; std::cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << std::endl; std::cout << " THE ZERO DIMENSIONAL SOLVER IS AN ALPHA VERSION UNDER STRONG DEVELOPMENT" << std::endl; std::cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << std::endl << std::endl; std::cout << "MPI Processes: " << numberOfProcesses << std::endl; } #ifdef HAVE_MPI if ( numberOfProcesses > 1 ) { if ( rank == 0 ) { std::cout << "test_ZeroDimensional not enabled in parallel, failing gracefully." << std::endl; std::cout << "MPI Finalization" << std::endl; } MPI_Finalize(); return EXIT_FAILURE; } #endif #ifdef EPETRA_MPI if ( rank == 0 ) { std::cout << "MPI Epetra Initialization ... " << std::endl; } comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) ); #else std::cout << "SERIAL Epetra Initialization ... " << std::endl; comm.reset ( new Epetra_SerialComm() ); #endif bool exitFlag = EXIT_SUCCESS; #if ( defined(HAVE_NOX_THYRA) && defined(HAVE_TRILINOS_RYTHMOS) ) // Command line parameters GetPot commandLine ( argc, argv ); const bool check = commandLine.search ( 2, "-c", "--check" ); string fileName = commandLine.follow ( "data", 2, "-f", "--file" ); // SetupData GetPot dataFile ( fileName + ".dat" ); std::string circuitDataFile = dataFile ( "0D_Model/CircuitDataFile", "./inputFile.dat" ); BCInterface0D< ZeroDimensionalBCHandler, ZeroDimensionalData > zeroDimensionalBC; zeroDimensionalBC.createHandler(); zeroDimensionalBC.fillHandler ( circuitDataFile, "Files" ); boost::shared_ptr< ZeroDimensionalData > zeroDimensionalData ( new ZeroDimensionalData ); zeroDimensionalData->setup ( dataFile, zeroDimensionalBC.handler() ); boost::shared_ptr< ZeroDimensionalSolver > zeroDimensionalSolver ( new ZeroDimensionalSolver ( zeroDimensionalData->unknownCounter(), comm, zeroDimensionalData->circuitData() ) ); zeroDimensionalSolver->setup ( zeroDimensionalData->solverData() ); zeroDimensionalData->showMe(); // SetupModel zeroDimensionalData->dataTime()->setInitialTime (0); zeroDimensionalData->initializeSolution(); // Create output folder if ( comm->MyPID() == 0 ) { mkdir ( "output", 0777 ); } // Save initial solution zeroDimensionalData->saveSolution(); zeroDimensionalData->dataTime()->updateTime(); zeroDimensionalData->dataTime()->setInitialTime (zeroDimensionalData->dataTime()->time() ); // Definitions for the time loop LifeChrono chronoTotal; LifeChrono chronoSystem; LifeChrono chronoIteration; Int count = 0; chronoTotal.start(); for ( ; zeroDimensionalData->dataTime()->canAdvance() ; zeroDimensionalData->dataTime()->updateTime(), ++count ) { std::cout << std::endl << "--------- Iteration " << count << " time = " << zeroDimensionalData->dataTime()->time() << std::endl; chronoIteration.start(); chronoSystem.start(); zeroDimensionalSolver->takeStep ( zeroDimensionalData->dataTime()->previousTime(), zeroDimensionalData->dataTime()->time() ); chronoSystem.stop(); //Save solution zeroDimensionalData->saveSolution(); chronoIteration.stop(); std::cout << " System solved in " << chronoSystem.diff() << " s, (total time " << chronoIteration.diff() << " s)." << std::endl; } chronoTotal.stop(); std::cout << std::endl << " Simulation ended successfully in " << chronoTotal.diff() << " s" << std::endl; // Final check if ( check ) { bool ok = true; ok = ok && checkValue ( 0.001329039627, zeroDimensionalData->circuitData()->Nodes()->nodeListAt (1)->voltage() ); ok = ok && checkValue ( 0.000787475119, zeroDimensionalData->circuitData()->Elements()->elementListAt (1)->current() ); if (ok) { std::cout << " Test succesful" << std::endl; exitFlag = EXIT_SUCCESS; } else { std::cout << " Test unsuccesful" << std::endl; exitFlag = EXIT_FAILURE; } } #else std::cout << "ZeroDimensional requires configuring Trilinos with Rythmos/NOX/Thyra. Skipping test." << std::endl; exitFlag = EXIT_SUCCESS; #endif /* HAVE_NOX_THYRA && HAVE_TRILINOS_RYTHMOS */ if (rank == 0) { std::cout << "End Result: TEST PASSED" << std::endl; } #ifdef HAVE_MPI if ( rank == 0 ) { std::cout << "MPI Finalization" << std::endl; } MPI_Finalize(); #endif return exitFlag; }