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 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[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); { boost::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD)); #else std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm) ; #endif typedef RegionMesh<LinearTetra> mesh_Type; if (Comm->MyPID()==0) std::cout << "Testing solver class..." << std::endl; bool verbose = true; // Load data GetPot command_line(argc,argv); const std::string dataFileName = command_line.follow("data",2,"-f","--file"); GetPot dataFile(dataFileName); // Build mesh if(verbose && Comm->MyPID() == 0 ) std::cout << "[Loading mesh]" << std::endl; meshPtr_Type fullMeshPtr(new mesh_Type(Comm)); regularMesh3D( *fullMeshPtr , 0 , dataFile("mesh/nx",15) , dataFile("mesh/ny",15) , dataFile("mesh/nz",15) , dataFile("mesh/verbose",false) , 2.0 , 2.0 , 2.0 , -1.0 , -1.0 , -1.0 ) ; const UInt overlap(dataFile("mesh/overlap",0)); meshPtr_Type localMeshPtr; { MeshPartitioner<mesh_Type> meshPart; if (overlap) meshPart.setPartitionOverlap(overlap); meshPart.doPartition(fullMeshPtr , Comm); localMeshPtr = meshPart.meshPartition(); } fullMeshPtr.reset(); // manage bc const int BACK = 1; const int FRONT = 2; const int LEFT = 3; const int RIGHT = 4; const int TOP = 5; const int BOTTOM = 6; BCHandler bcHandler; BCFunctionBase ZeroBC (zeroFunction) ; bcHandler.addBC("Back", BACK , Essential , Scalar , ZeroBC , 1) ; bcHandler.addBC("Left" , LEFT , Essential , Scalar , ZeroBC , 1); bcHandler.addBC("Top" , TOP , Essential , Scalar , ZeroBC , 1); bcHandler.addBC("Front" , FRONT , Essential , Scalar , ZeroBC , 1); bcHandler.addBC("Right" , RIGHT , Essential , Scalar , ZeroBC , 1); bcHandler.addBC("Bottom" , BOTTOM , Essential , Scalar , ZeroBC , 1); // Set exporter ExporterHDF5 <mesh_Type > exporter (dataFile , "fwd"); exporter.setMeshProcId (localMeshPtr , Comm->MyPID()); exporter.setPrefix("test_fwd"); exporter.setPostDir("./"); // Instantiate class InverseETAEllipticSolver<mesh_Type> solver( dataFile , localMeshPtr , "SolverParamList2.xml" , bcHandler , &torsoLocation ); solver.solveFwd(exporter); // Exporter post-processing exporter.postProcess(0); exporter.closeFile(); // // Assemble matrix and rhs // if(verbose) // std::cout << "[Building graph and matrix]" << std::endl; // graphPtr_Type systemGraph; // matrixPtr_Type systemMatrix; // if (overlap) // { // systemGraph.reset( new graph_Type( Copy , * (uFESpace->map().map(Unique)), // 50,true ) ); // } // else // { // systemGraph.reset( new graph_Type( Copy , * (uFESpace->map().map(Unique)), // 50 ) ); // } // { // using namespace ExpressionAssembly ; // buildGraph ( // elements(localMeshPtr) , // uFESpace->qr() , // ETuFESpace, // ETuFESpace, // dot(grad(phi_i) , grad(phi_j) ) // ) // >> systemGraph ; // } // systemGraph->GlobalAssemble(); // if(overlap) // { // systemMatrix.reset( new matrix_Type ( ETuFESpace->map() , *systemGraph , true)); // } // else // { // systemMatrix.reset( new matrix_Type ( ETuFESpace->map() , *systemGraph )); // } // systemMatrix->zero(); // { // using namespace ExpressionAssembly; // integrate ( // elements(localMeshPtr) , // uFESpace->qr() , // ETuFESpace, // ETuFESpace, // dot (grad ( phi_i) , grad(phi_j) ) // ) // >> systemMatrix ; // } #ifdef HAVE_MPI } MPI_Finalize(); #endif return EXIT_SUCCESS; }
int main (int argc, char** argv) { #ifdef LIFEV_HAS_HDF5 #ifdef HAVE_MPI typedef RegionMesh<LinearTetra> mesh_Type; MPI_Init (&argc, &argv); boost::shared_ptr<Epetra_Comm> comm (new Epetra_MpiComm (MPI_COMM_WORLD) ); if (comm->NumProc() != 1) { std::cout << "This test needs to be run " << "with a single process. Aborting." << std::endl; return (EXIT_FAILURE); } GetPot commandLine (argc, argv); string dataFileName = commandLine.follow ("data", 2, "-f", "--file"); GetPot dataFile (dataFileName); const UInt numElements (dataFile ("mesh/nelements", 10) ); const UInt numParts (dataFile ("test/num_parts", 4) ); const std::string partsFileName (dataFile ("test/hdf5_file_name", "cube.h5") ); const std::string ioClass (dataFile ("test/io_class", "new") ); std::cout << "Number of elements in mesh: " << numElements << std::endl; std::cout << "Number of parts: " << numParts << std::endl; std::cout << "Name of HDF5 container: " << partsFileName << std::endl; boost::shared_ptr<mesh_Type> fullMeshPtr (new mesh_Type ( comm ) ); regularMesh3D (*fullMeshPtr, 1, numElements, numElements, numElements, false, 2.0, 2.0, 2.0, -1.0, -1.0, -1.0); MeshPartitioner<mesh_Type> meshPart; meshPart.setup (numParts, comm); meshPart.attachUnpartitionedMesh (fullMeshPtr); meshPart.doPartitionGraph(); meshPart.doPartitionMesh(); // Release the original mesh from the MeshPartitioner object and // delete the RegionMesh object meshPart.releaseUnpartitionedMesh(); fullMeshPtr.reset(); // Write mesh parts to HDF5 container if (! ioClass.compare ("old") ) { ExporterHDF5Mesh3D<mesh_Type> HDF5Output (dataFile, meshPart.meshPartition(), partsFileName, comm->MyPID() ); HDF5Output.addPartitionGraph (meshPart.elementDomains(), comm); HDF5Output.addMeshPartitionAll (meshPart.meshPartitions(), comm); HDF5Output.postProcess (0); HDF5Output.closeFile(); } else { boost::shared_ptr<Epetra_MpiComm> mpiComm = boost::dynamic_pointer_cast<Epetra_MpiComm> (comm); PartitionIO<mesh_Type> partitionIO (partsFileName, mpiComm); partitionIO.write (meshPart.meshPartitions() ); } MPI_Finalize(); #else std::cout << "This test needs MPI to run. Aborting." << std::endl; return (EXIT_FAILURE); #endif /* HAVE_MPI */ #else std::cout << "This test needs HDF5 to run. Aborting." << std::endl; return (EXIT_FAILURE); #endif /* LIFEV_HAS_HDF5 */ return (EXIT_SUCCESS); }
int main ( int argc, char** argv ) { bool verbose (false); #ifdef HAVE_MPI MPI_Init (&argc, &argv); boost::shared_ptr<Epetra_Comm> Comm ( new Epetra_MpiComm (MPI_COMM_WORLD) ); if ( Comm->MyPID() == 0 ) { verbose = true; } #else boost::shared_ptr<Epetra_Comm> Comm( new Epetra_SerialComm () ); verbose = true; #endif typedef RegionMesh< LinearTetra > mesh_Type; typedef FESpace< mesh_Type, MapEpetra > uSpaceStd_Type; typedef boost::shared_ptr< uSpaceStd_Type > uSpaceStdPtr_Type; typedef ETFESpace< mesh_Type, MapEpetra, 3, 3 > uSpaceETA_Type; typedef ETFESpace< mesh_Type, MapEpetra, 3, 3 > uSpaceETAVectorial_Type; typedef boost::shared_ptr< uSpaceETA_Type > uSpaceETAPtr_Type; typedef boost::shared_ptr< uSpaceETAVectorial_Type > uSpaceETAVectorialPtr_Type; typedef FESpace<mesh_Type, MapEpetra>::function_Type function_Type; typedef MatrixEpetra< Real > matrix_Type; typedef boost::shared_ptr< MatrixEpetra< Real > > matrixPtr_Type; typedef VectorEpetra vector_Type; typedef boost::shared_ptr<VectorEpetra> vectorPtr_Type; // DATAFILE GetPot command_line ( argc, argv ); const std::string dataFileName = command_line.follow ( "data", 2, "-f", "--file" ); GetPot dataFile ( dataFileName ); // GENERAZIONE MESH boost::shared_ptr< mesh_Type > fullMeshPtr ( new mesh_Type ( Comm ) ); MeshData meshData; meshData.setup (dataFile, "space_discretization"); readMesh (*fullMeshPtr, meshData); // CREAZIONE CONNETTIVITA MESH uSpaceStdPtr_Type uFESpace_serial ( new uSpaceStd_Type ( fullMeshPtr, dataFile ("finite_element/degree", "P1"), 3, Comm ) ); BuildReducedMesh RedMeshGenerator(uFESpace_serial); uFESpace_serial.reset(); // PARTIZIONAMENTO MESH boost::shared_ptr< mesh_Type > localMeshPtr; MeshPartitioner< mesh_Type > meshPart; meshPart.doPartition ( fullMeshPtr, Comm ); localMeshPtr = meshPart.meshPartition(); //fullMeshPtr.reset(); // SPAZI ELEMENTI FINITI uSpaceStdPtr_Type uFESpace ( new uSpaceStd_Type ( localMeshPtr, dataFile ("finite_element/degree", "P1"), 3, Comm ) ); uSpaceETAPtr_Type ETuFESpace ( new uSpaceETA_Type ( localMeshPtr, & ( uFESpace->refFE() ), & ( uFESpace->fe().geoMap() ), Comm ) ); // OGGETTI PER VISUALIZZAZIONE MESH RIDOTTA uSpaceStdPtr_Type FESpace_reducedMesh ( new uSpaceStd_Type ( fullMeshPtr, dataFile ("finite_element/degree", "P1"), 1, Comm ) ); vectorPtr_Type reduced_mesh ( new vector_Type ( FESpace_reducedMesh->map(), Unique ) ); reduced_mesh->zero(); ExporterHDF5< mesh_Type > exporter_reduced_mesh ( dataFile, "exporter" ); exporter_reduced_mesh.setMeshProcId( localMeshPtr, Comm->MyPID() ); exporter_reduced_mesh.setPrefix( dataFile ("exporter/name_output_reduced_mesh", "ReducedMesh") ); exporter_reduced_mesh.setPostDir( "./" ); exporter_reduced_mesh.addVariable ( ExporterData< mesh_Type >::ScalarField, "reduced mesh", FESpace_reducedMesh, reduced_mesh, UInt ( 0 ) ); // Offset componenti int offsetComponent = uFESpace->dof().numTotalDof(); int numSolSnapshots; EpetraExt::HDF5 HDF5_importer(*Comm); HDF5_importer.Open( dataFile ("name_output_file_system/name_input_file_solution", "SolSnapshots")+".h5" ); std::string h5_sol_prefix = dataFile("solution/prefix", "sol"); HDF5_importer.Read("info", "num_"+h5_sol_prefix+"Snapshots", numSolSnapshots); HDF5_importer.Close(); // --------------------------- // HDF5 file managers // --------------------------- EpetraExt::HDF5 HDF5_exporter( *Comm ); HDF5_exporter.Create( dataFile("rom_exporter/name_output_file", "ROM")+".h5" ); DenseHDF5 HDF5dense_exporter; if ( Comm->MyPID() == 0 ) { HDF5dense_exporter.Create( dataFile("rom_exporter/hyper_output_file", "Hyper_ROM")+".h5" ); } std::string JacobianApproximation = dataFile ("hyperreduction/jacobian_approximation", "DEIM"); bool SplitInternalForces = dataFile ("hyperreduction/split_internal_force", false); // --------------------------- // Build FE Matrix Map rows in the internal dofs // --------------------------- boost::shared_ptr<BCHandler> bc_markingDOFs = BCh_marking (); bc_markingDOFs->bcUpdate( *uFESpace->mesh(), uFESpace->feBd(), uFESpace->dof() ); boost::shared_ptr<DOF_Extractor> dofExtractor; dofExtractor.reset ( new DOF_Extractor ( uFESpace ) ); dofExtractor->setup( bc_markingDOFs ); mapPtr_Type map_rows; map_rows.reset ( new MapEpetra ( *dofExtractor->getMapUnmarked() ) ); // --------------------------- // Build Reduced Basis for the solution // --------------------------- ReductionVector RBsol(dataFile, "solution", Comm, map_rows); RBsol.perform(); RBsol.write(HDF5_exporter, HDF5dense_exporter); boost::shared_ptr<Epetra_FECrsMatrix> V; RBsol.getPODbasis(V); int numSolBases = RBsol.getNumBases(); // --------------------------- // Hyper Reduce RHS Internal ISO Forces // --------------------------- HyperReductionVector HyperFIiso( dataFile, "residual_internal_force_iso", Comm, map_rows); HyperFIiso.perform(); HyperFIiso.write(HDF5dense_exporter); HyperFIiso.project(V, numSolBases, HDF5_exporter); std::vector<int> deim_FIiso_GID = HyperFIiso.getDeimGID(); if (JacobianApproximation=="DEIM") { HyperFIiso.DEIMjacobianLeftProjection(V, HDF5_exporter, "DEIMjacobianLeftProjection_iso"); } // --------------------------- // Hyper Reduce RHS Internal VOL Forces // --------------------------- HyperReductionVector HyperFIvol( dataFile, "residual_internal_force_vol", Comm, map_rows); HyperFIvol.perform(); HyperFIvol.write(HDF5dense_exporter); HyperFIvol.project(V, numSolBases, HDF5_exporter); std::vector<int> deim_FIvol_GID = HyperFIvol.getDeimGID(); if (JacobianApproximation=="DEIM") { HyperFIvol.DEIMjacobianLeftProjection(V, HDF5_exporter, "DEIMjacobianLeftProjection_vol"); } // --------------------------- // Hyper Reduce RHS External Forces // --------------------------- HyperReductionVector HyperFE( dataFile, "residual_external_force", Comm, map_rows); HyperFE.perform(); HyperFE.write(HDF5dense_exporter); HyperFE.project(V, numSolBases, HDF5_exporter); std::vector<int> deim_FE_GID = HyperFE.getDeimGID(); // --------------------------- // Hyper Reduce MATRIX // --------------------------- if (JacobianApproximation=="MDEIM") { HyperReductionMatrix HyperA( dataFile, "jacobian_matrix", Comm, map_rows); HyperA.perform(); HyperA.write(HDF5dense_exporter); HyperA.project(V, numSolBases, HDF5_exporter); std::vector<int> deim_A_GID = HyperA.getDeimDofs(); RedMeshGenerator.appendSelectedDofs(deim_A_GID); } // --------------------------- // Build Reduced Mesh // --------------------------- RedMeshGenerator.appendSelectedDofs(deim_FIiso_GID); RedMeshGenerator.appendSelectedDofs(deim_FIvol_GID); RedMeshGenerator.appendSelectedDofs(deim_FE_GID); RedMeshGenerator.DofsToNodes_CSM(); RedMeshGenerator.build(FESpace_reducedMesh, reduced_mesh, HDF5dense_exporter); exporter_reduced_mesh.postProcess(0.0); exporter_reduced_mesh.closeFile(); // close HDF5 file manager HDF5_exporter.Close(); if ( Comm->MyPID() == 0 ) { HDF5dense_exporter.Close(); } #ifdef HAVE_MPI if (verbose) { std::cout << "\nMPI Finalization\n" << std::endl; } MPI_Finalize(); #endif return ( EXIT_SUCCESS ); }
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; } } }
int main (int argc, char** argv ) { typedef FESpace < RegionMesh<LinearTetra>, MapEpetra > FESpaceTetra_Type; typedef boost::shared_ptr < FESpaceTetra_Type > FESpaceTetraPtr_Type; typedef FESpace < RegionMesh<LinearHexa>, MapEpetra > FESpaceHexa_Type; typedef boost::shared_ptr < FESpaceHexa_Type > FESpaceHexaPtr_Type; #ifdef HAVE_MPI MPI_Init (&argc, &argv); boost::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) ); #else boost::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm); #endif UInt verbose = (Comm->MyPID() == 0); bool check (true); //definition of Array of Errors which will be used to check the correctness of the interpolate test. const Real errArrayBilinear[2] = { 0.0312819802, 0. }; const Real errArrayQuadratic[12] = { 0.0136247667, 0.0005088372, 0.0005577494, 0.0005088372, 0.0136172446, 0.0005088372, 0.0004270717, 0.0005088372, 0.0136172446, 0.0005088372, 0.0004270717, 0. }; const Real errArrayBubble[12] = { 0.0094702745, 3.584186e-10, 3.67611e-10, 3.584186e-10, 0.0094702745, 3.584186e-10, 0., 3.584186e-10, 0.0094702745, 3.584186e-10, 3.67611e-10, 3.584186e-10 }; const Real errArrayLinear[12] = { 0.010437463587, 0., 0., 0., 0.010437463587, 0., 0., 0., 0.010437463587, 0., 0., 0. }; const std::string stringArrayP[12] = { "P1 -> P0 ", "P1 -> P1 ", "P1 -> P1b", "P1 -> P2 ", "P1b -> P0 ", "P1b -> P1 ", "P1b -> P1b", "P1b -> P2 ", "P2 -> P0 ", "P2 -> P1 ", "P2 -> P1b", "P2 -> P2 " }; const std::string stringArrayQ[2] = {"Q1 -> Q0 ", "Q1 -> Q1 "}; // Import/Generate an hexahedral and a Tetrahedral mesh. boost::shared_ptr<RegionMesh<LinearTetra> > fullMeshTetraPtr ( new RegionMesh<LinearTetra> ( Comm ) ); boost::shared_ptr<RegionMesh<LinearHexa> > fullMeshHexaPtr ( new RegionMesh<LinearHexa> ( Comm ) ); UInt nEl (10); GetPot dataFile ("./data"); MeshData meshData (dataFile, "interpolate/space_discretization"); readMesh (*fullMeshHexaPtr, meshData); regularMesh3D ( *fullMeshTetraPtr, 1, nEl, nEl, nEl); // Partition the meshes using ParMetis boost::shared_ptr<RegionMesh<LinearHexa> > localMeshHexaPtr; { // Create the partitioner MeshPartitioner< RegionMesh<LinearHexa> > meshPartHexa; // Partition the mesh using ParMetis meshPartHexa.doPartition ( fullMeshHexaPtr, Comm ); // Get the local mesh localMeshHexaPtr = meshPartHexa.meshPartition(); } boost::shared_ptr<RegionMesh<LinearTetra> > localMeshTetraPtr; { // Create the partitioner MeshPartitioner< RegionMesh<LinearTetra> > meshPartTetra; // Partition the mesh using ParMetis meshPartTetra.doPartition ( fullMeshTetraPtr, Comm ); // Get the local mesh localMeshTetraPtr = meshPartTetra.meshPartition(); } //Building finite element spaces //Finite element space of the first scalar field - P0 FESpaceTetraPtr_Type feSpaceP0 ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP0, quadRuleTetra4pt, quadRuleTria4pt, 3, Comm ) ); //Finite element space of the second scalar field - P1 FESpaceTetraPtr_Type feSpaceP1 ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP1, quadRuleTetra4pt, quadRuleTria4pt, 3, Comm ) ); // Finite element space of the second scalar field - P1bubble FESpaceTetraPtr_Type feSpaceP1Bubble ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP1bubble, quadRuleTetra15pt, quadRuleTria4pt, 3, Comm ) ); // Finite element space of the second scalar field - P2 FESpaceTetraPtr_Type feSpaceP2 ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP2, quadRuleTetra4pt, quadRuleTria4pt, 3, Comm ) ); // Finite element space of the first scalar field - Q0 FESpaceHexaPtr_Type feSpaceQ0 ( new FESpaceHexa_Type ( localMeshHexaPtr, feHexaQ0, quadRuleHexa8pt, quadRuleQuad4pt, 2, Comm ) ); // Finite element space of the second scalar field - Q1 FESpaceHexaPtr_Type feSpaceQ1 ( new FESpaceHexa_Type ( localMeshHexaPtr, feHexaQ1, quadRuleHexa8pt, quadRuleQuad4pt, 2, Comm ) ); //vectors containing the original and final FE spaces //(FE vectors will be interpolated from original FE spaces into final FE Spaces) std::vector<FESpaceHexaPtr_Type > originalFeSpaceHexaVec (1), finalFeSpaceHexaVec (2); std::vector<FESpaceTetraPtr_Type> originalFeSpaceTetraVec (3), finalFeSpaceTetraVec (4); originalFeSpaceHexaVec[0] = feSpaceQ1; finalFeSpaceHexaVec[0] = feSpaceQ0; finalFeSpaceHexaVec[1] = feSpaceQ1; originalFeSpaceTetraVec[0] = feSpaceP1; originalFeSpaceTetraVec[1] = feSpaceP1Bubble; originalFeSpaceTetraVec[2] = feSpaceP2; finalFeSpaceTetraVec[0] = feSpaceP0; finalFeSpaceTetraVec[1] = feSpaceP1; finalFeSpaceTetraVec[2] = feSpaceP1Bubble; finalFeSpaceTetraVec[3] = feSpaceP2; Real time = 0.5; if (verbose) { std::cout << "\nA bilinear function is interpolated into Q1 vector. \nThen this FE vector is interpolated into Q0 and Q1 vectors. \nThese are the errors with respect to the analytical solution.\n"; } check = check_interpolate (originalFeSpaceHexaVec, finalFeSpaceHexaVec, Unique, bilinearFunction, errArrayBilinear, stringArrayQ, 1e-10, time, verbose); if (verbose) std::cout << "\nA linear function is interpolated into P1, P1b, P2 vectors. " "\nThen these FE vectors are interpolated into the following finite elements \nand error with respect to the analytic solution are reported.\n"; check &= check_interpolate (originalFeSpaceTetraVec, finalFeSpaceTetraVec, Repeated, linearFunction, errArrayLinear, stringArrayP, 1e-10, time, verbose); if (verbose) std::cout << "\nA quadratic function is interpolated into P1, P1b, P2 vectors. " "\nThen these FE vectors are interpolated into the following finite elements \nand error with respect to the analytic solution are reported.\n"; check &= check_interpolate (originalFeSpaceTetraVec, finalFeSpaceTetraVec, Unique, quadraticFunction, errArrayQuadratic, stringArrayP, 1e-10, time, verbose); if (verbose) std::cout << "\nA linear bubble function is interpolated into P1, P1b, P2 vectors. " "\nThen these FE vectors are interpolated into the following finite elements \nand error with respect to the analytic solution are reported.\n"; check &= check_interpolate (originalFeSpaceTetraVec, finalFeSpaceTetraVec, Repeated, linearBubbleFunction, errArrayBubble, stringArrayP, 1e-10, time, verbose); #ifdef HAVE_MPI std::cout << "MPI Finalization" << std::endl; MPI_Finalize(); #endif if (verbose) { if (check) { std::cout << "\nTEST INTERPOLATE WAS SUCCESSFUL.\n\n"; } else { std::cout << "\nTEST INTERPOLATE FAILED.\n\n"; } } if (check) { return EXIT_SUCCESS; } else { return EXIT_FAILURE; } }//end main