void Bidomain::DoOdeRhs( const Array<OneD, const Array<OneD, NekDouble> >&inarray, Array<OneD, Array<OneD, NekDouble> >&outarray, const NekDouble time) { int nq = m_fields[0]->GetNpoints(); m_cell->TimeIntegrate(inarray, outarray, time); if (m_stimDuration > 0 && time < m_stimDuration) { Array<OneD,NekDouble> x0(nq); Array<OneD,NekDouble> x1(nq); Array<OneD,NekDouble> x2(nq); Array<OneD,NekDouble> result(nq); // get the coordinates m_fields[0]->GetCoords(x0,x1,x2); LibUtilities::EquationSharedPtr ifunc = m_session->GetFunction("Stimulus", "u"); ifunc->Evaluate(x0,x1,x2,time, result); Vmath::Vadd(nq, outarray[0], 1, result, 1, outarray[0], 1); } Vmath::Smul(nq, 1.0/m_capMembrane, outarray[0], 1, outarray[0], 1); }
void Forcing::EvaluateFunction( Array<OneD, MultiRegions::ExpListSharedPtr> pFields, LibUtilities::SessionReaderSharedPtr pSession, std::string pFieldName, Array<OneD, NekDouble>& pArray, const std::string& pFunctionName, NekDouble pTime) { ASSERTL0(pSession->DefinesFunction(pFunctionName), "Function '" + pFunctionName + "' does not exist."); unsigned int nq = pFields[0]->GetNpoints(); if (pArray.num_elements() != nq) { pArray = Array<OneD, NekDouble> (nq); } LibUtilities::FunctionType vType; vType = pSession->GetFunctionType(pFunctionName, pFieldName); if (vType == LibUtilities::eFunctionTypeExpression) { Array<OneD, NekDouble> x0(nq); Array<OneD, NekDouble> x1(nq); Array<OneD, NekDouble> x2(nq); pFields[0]->GetCoords(x0, x1, x2); LibUtilities::EquationSharedPtr ffunc = pSession->GetFunction(pFunctionName, pFieldName); ffunc->Evaluate(x0, x1, x2, pTime, pArray); } else if (vType == LibUtilities::eFunctionTypeFile) { std::string filename = pSession->GetFunctionFilename( pFunctionName, pFieldName); std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef; std::vector<std::vector<NekDouble> > FieldData; Array<OneD, NekDouble> vCoeffs(pFields[0]->GetNcoeffs()); Vmath::Zero(vCoeffs.num_elements(), vCoeffs, 1); LibUtilities::FieldIOSharedPtr fld = MemoryManager<LibUtilities::FieldIO>::AllocateSharedPtr(m_session->GetComm()); fld->Import(filename, FieldDef, FieldData); int idx = -1; for (int i = 0; i < FieldDef.size(); ++i) { for (int j = 0; j < FieldDef[i]->m_fields.size(); ++j) { if (FieldDef[i]->m_fields[j] == pFieldName) { idx = j; } } if (idx >= 0) { pFields[0]->ExtractDataToCoeffs( FieldDef[i], FieldData[i], FieldDef[i]->m_fields[idx], vCoeffs); } else { cout << "Field " + pFieldName + " not found." << endl; } } pFields[0]->BwdTrans_IterPerExp(vCoeffs, pArray); } }
void VelocityCorrectionScheme::v_InitObject() { int n; IncNavierStokes::v_InitObject(); m_explicitDiffusion = false; // Set m_pressure to point to last field of m_fields; if (boost::iequals(m_session->GetVariable(m_fields.num_elements()-1), "p")) { m_nConvectiveFields = m_fields.num_elements()-1; m_pressure = m_fields[m_nConvectiveFields]; } else { ASSERTL0(false,"Need to set up pressure field definition"); } // Determine equations on which SVV is activated m_useSpecVanVisc = Array<OneD, bool> (m_nConvectiveFields, false); m_sVVCutoffRatio = Array<OneD, NekDouble> (m_nConvectiveFields, 0.75); m_sVVDiffCoeff = Array<OneD, NekDouble> (m_nConvectiveFields, 0.1); m_useHomo1DSpecVanVisc = Array<OneD, bool> (m_nConvectiveFields, false); // Determine diffusion coefficients for each field m_diffCoeff = Array<OneD, NekDouble> (m_nConvectiveFields, m_kinvis); for (n = 0; n < m_nConvectiveFields; ++n) { std::string varName = m_session->GetVariable(n); if ( m_session->DefinesFunction("DiffusionCoefficient", varName)) { LibUtilities::EquationSharedPtr ffunc = m_session->GetFunction("DiffusionCoefficient", varName); m_diffCoeff[n] = ffunc->Evaluate(); } if (m_session->DefinesFunction("SVVCutoffRatio", varName)) { m_useSpecVanVisc[n] = true; LibUtilities::EquationSharedPtr ffunc = m_session->GetFunction("SVVcutoffRatio", varName); m_sVVCutoffRatio[n] = ffunc->Evaluate(); } if (m_session->DefinesFunction("SVVDiffCoeff", varName)) { ASSERTL0(m_useSpecVanVisc[n], "SVV cut off ratio is not set for the variable:" + varName); LibUtilities::EquationSharedPtr ffunc = m_session->GetFunction("SVVDiffCoeff", varName); m_sVVDiffCoeff[n] = ffunc->Evaluate(); } } // creation of the extrapolation object if(m_equationType == eUnsteadyNavierStokes) { std::string vExtrapolation = "Standard"; if (m_session->DefinesSolverInfo("Extrapolation")) { vExtrapolation = m_session->GetSolverInfo("Extrapolation"); } m_extrapolation = GetExtrapolateFactory().CreateInstance( vExtrapolation, m_session, m_fields, m_pressure, m_velocity, m_advObject); } // Integrate only the convective fields for (n = 0; n < m_nConvectiveFields; ++n) { m_intVariables.push_back(n); } m_saved_aii_Dt = Array<OneD, NekDouble>(m_nConvectiveFields, NekConstants::kNekUnsetDouble); // Load parameters for Spectral Vanishing Viscosity /* m_session->MatchSolverInfo("SpectralVanishingViscosity","True", m_useSpecVanVisc,false); m_session->LoadParameter("SVVCutoffRatio",m_sVVCutoffRatio,0.75); m_session->LoadParameter("SVVDiffCoeff", m_sVVDiffCoeff, 0.1); // Needs to be set outside of next if so that it is turned off by default m_session->MatchSolverInfo("SpectralVanishingViscosityHomo1D","True", m_useHomo1DSpecVanVisc,false); */ m_session->MatchSolverInfo("SPECTRALHPDEALIASING","True", m_specHP_dealiasing,false); if(m_HomogeneousType == eHomogeneous1D) { ASSERTL0(m_nConvectiveFields > 2,"Expect to have three velocity fields with homogenous expansion"); /* if(m_useHomo1DSpecVanVisc == false) { m_session->MatchSolverInfo("SpectralVanishingViscosity","True",m_useHomo1DSpecVanVisc,false); } */ for (int i = 0; i < m_nConvectiveFields; ++i) { m_useHomo1DSpecVanVisc[i] = m_useSpecVanVisc[i]; if(m_useHomo1DSpecVanVisc[i]) { Array<OneD, unsigned int> planes; planes = m_fields[0]->GetZIDs(); int num_planes = planes.num_elements(); Array<OneD, NekDouble> SVV(num_planes,0.0); NekDouble fac; int kmodes = m_fields[0]->GetHomogeneousBasis()->GetNumModes(); int pstart; pstart = m_sVVCutoffRatio[i]*kmodes; for(n = 0; n < num_planes; ++n) { if(planes[n] > pstart) { fac = (NekDouble)((planes[n] - kmodes)*(planes[n] - kmodes))/ ((NekDouble)((planes[n] - pstart)*(planes[n] - pstart))); SVV[n] = m_sVVDiffCoeff[i]*exp(-fac)/m_diffCoeff[i]; } } /* for(int j = 0; j < m_velocity.num_elements(); ++j) { m_fields[m_velocity[j]]->SetHomo1DSpecVanVisc(SVV); } */ m_fields[i]->SetHomo1DSpecVanVisc(SVV); } } } m_session->MatchSolverInfo("SmoothAdvection", "True", m_SmoothAdvection, false); // set explicit time-intregration class operators m_ode.DefineOdeRhs(&VelocityCorrectionScheme::EvaluateAdvection_SetPressureBCs, this); m_extrapolation->SubSteppingTimeIntegration(m_intScheme->GetIntegrationMethod(), m_intScheme); m_extrapolation->GenerateHOPBCMap(); // set implicit time-intregration class operators m_ode.DefineImplicitSolve(&VelocityCorrectionScheme::SolveUnsteadyStokesSystem,this); }
int main(int argc, char *argv[]) { SpatialDomains::PointGeomSharedPtr vPoint; MultiRegions::ExpListSharedPtr vExp; LibUtilities::SessionReaderSharedPtr vSession; std::string vCellModel; CellModelSharedPtr vCell; std::vector<StimulusSharedPtr> vStimulus; Array<OneD, Array<OneD, NekDouble> > vWsp(1); Array<OneD, Array<OneD, NekDouble> > vSol(1); NekDouble vDeltaT; NekDouble vTime; unsigned int nSteps; // Create a session reader to read pacing parameters vSession = LibUtilities::SessionReader::CreateInstance(argc, argv); try { // Construct a field consisting of a single vertex vPoint = MemoryManager<SpatialDomains::PointGeom> ::AllocateSharedPtr(3, 0, 0.0, 0.0, 0.0); vExp = MemoryManager<MultiRegions::ExpList0D> ::AllocateSharedPtr(vPoint); // Get cell model name and create it vSession->LoadSolverInfo("CELLMODEL", vCellModel, ""); ASSERTL0(vCellModel != "", "Cell Model not specified."); vCell = GetCellModelFactory().CreateInstance( vCellModel, vSession, vExp); vCell->Initialise(); // Load the stimuli vStimulus = Stimulus::LoadStimuli(vSession, vExp); // Set up solution arrays, workspace and read in parameters vSol[0] = Array<OneD, NekDouble>(1, 0.0); vWsp[0] = Array<OneD, NekDouble>(1, 0.0); vDeltaT = vSession->GetParameter("TimeStep"); vTime = 0.0; nSteps = vSession->GetParameter("NumSteps"); LibUtilities::EquationSharedPtr e = vSession->GetFunction("InitialConditions", "u"); vSol[0][0] = e->Evaluate(0.0, 0.0, 0.0, 0.0); // Time integrate cell model for (unsigned int i = 0; i < nSteps; ++i) { // Compute J_ion vCell->TimeIntegrate(vSol, vWsp, vTime); // Add stimuli J_stim for (unsigned int i = 0; i < vStimulus.size(); ++i) { vStimulus[i]->Update(vWsp, vTime); } // Time-step with forward Euler Vmath::Svtvp(1, vDeltaT, vWsp[0], 1, vSol[0], 1, vSol[0], 1); // Increment time vTime += vDeltaT; // Output current solution to stdout cout << vTime << " " << vSol[0][0] << endl; } for (unsigned int i = 0; i < vCell->GetNumCellVariables(); ++i) { cout << "# " << vCell->GetCellVarName(i) << " " << vCell->GetCellSolution(i)[0] << endl; } } catch (...) { cerr << "An error occured" << endl; } return 0; }
int main(int argc, char *argv[]) { LibUtilities::SessionReaderSharedPtr vSession = LibUtilities::SessionReader::CreateInstance(argc, argv); MultiRegions::ContField2DSharedPtr Exp,Fce; int nq, coordim; Array<OneD,NekDouble> fce; Array<OneD,NekDouble> xc0,xc1,xc2; NekDouble lambda; NekDouble ax,ay; if((argc != 2)&&(argc != 3)) { fprintf(stderr,"Usage: SteadyLinearAdvectionReaction2D meshfile [SysSolnType]\n"); exit(1); } //---------------------------------------------- // Read in mesh from input file SpatialDomains::MeshGraphSharedPtr graph2D = MemoryManager<SpatialDomains::MeshGraph2D>::AllocateSharedPtr(vSession); //---------------------------------------------- //---------------------------------------------- // Get Advection Velocity ax = vSession->GetParameter("Advection_x"); ay = vSession->GetParameter("Advection_y"); //---------------------------------------------- //---------------------------------------------- // Print summary of solution details lambda = vSession->GetParameter("Lambda"); cout << " Lambda : " << lambda << endl; const SpatialDomains::ExpansionMap &expansions = graph2D->GetExpansions(); LibUtilities::BasisKey bkey0 = expansions.begin()->second->m_basisKeyVector[0]; LibUtilities::BasisKey bkey1 = expansions.begin()->second->m_basisKeyVector[1]; cout << "Solving Steady 2D LinearAdvection :" << endl; cout << " Advection_x : " << ax << endl; cout << " Advection_y : " << ay << endl; cout << " Expansion : (" << LibUtilities::BasisTypeMap[bkey0.GetBasisType()] <<","<< LibUtilities::BasisTypeMap[bkey1.GetBasisType()] << ")" << endl; cout << " No. modes : " << bkey0.GetNumModes() << endl; cout << endl; //---------------------------------------------- //---------------------------------------------- // Define Expansion Exp = MemoryManager<MultiRegions::ContField2D>:: AllocateSharedPtr(vSession,graph2D,vSession->GetVariable(0)); //---------------------------------------------- Timing("Read files and define exp .."); //---------------------------------------------- // Set up coordinates of mesh for Forcing function evaluation coordim = Exp->GetCoordim(0); nq = Exp->GetTotPoints(); xc0 = Array<OneD,NekDouble>(nq,0.0); xc1 = Array<OneD,NekDouble>(nq,0.0); xc2 = Array<OneD,NekDouble>(nq,0.0); switch(coordim) { case 1: Exp->GetCoords(xc0); break; case 2: Exp->GetCoords(xc0,xc1); break; case 3: Exp->GetCoords(xc0,xc1,xc2); break; } Array<OneD, Array< OneD, NekDouble> > Vel(2); Vel[0] = Array<OneD, NekDouble> (nq,ax); Vel[1] = Array<OneD, NekDouble> (nq,ay); //---------------------------------------------- //---------------------------------------------- // Define forcing function for first variable defined in file fce = Array<OneD,NekDouble>(nq); LibUtilities::EquationSharedPtr ffunc = vSession->GetFunction("Forcing",0); ffunc->Evaluate(xc0,xc1,xc2,fce); //---------------------------------------------- //---------------------------------------------- // Setup expansion containing the forcing function Fce = MemoryManager<MultiRegions::ContField2D>::AllocateSharedPtr(*Exp); Fce->SetPhys(fce); //---------------------------------------------- Timing("Define forcing .."); //---------------------------------------------- // Helmholtz solution taking physical forcing Exp->LinearAdvectionReactionSolve(Vel, Fce->GetPhys(), Exp->UpdateCoeffs(), lambda, MultiRegions::eGlobal); //---------------------------------------------- Timing("Linear Advection Solve .."); //---------------------------------------------- // Backward Transform Solution to get solved values Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys(), MultiRegions::eGlobal); //---------------------------------------------- //---------------------------------------------- // See if there is an exact solution, if so // evaluate and plot errors LibUtilities::EquationSharedPtr ex_sol = vSession->GetFunction("ExactSolution",0); if(ex_sol) { //---------------------------------------------- // evaluate exact solution ex_sol->Evaluate(xc0,xc1,xc2,fce); //---------------------------------------------- //-------------------------------------------- // Calculate L_inf error Fce->SetPhys(fce); Fce->SetPhysState(true); cout << "L infinity error: " << Exp->Linf(Fce->GetPhys()) << endl; cout << "L 2 error: " << Exp->L2 (Fce->GetPhys()) << endl; //-------------------------------------------- } //---------------------------------------------- vSession->Finalise(); return 0; }
int main(int argc, char *argv[]) { LibUtilities::SessionReaderSharedPtr vSession = LibUtilities::SessionReader::CreateInstance(argc, argv); LibUtilities::CommSharedPtr vComm = vSession->GetComm(); string meshfile(argv[1]); MultiRegions::DisContField3DHomogeneous1DSharedPtr Exp,Fce; MultiRegions::ExpListSharedPtr DerExp1,DerExp2,DerExp3; int i, nq; Array<OneD,NekDouble> fce; Array<OneD,NekDouble> xc0,xc1,xc2; StdRegions::ConstFactorMap factors; NekDouble lz; if(argc != 2) { fprintf(stderr,"Usage: Helmholtz2D meshfile\n"); exit(1); } LibUtilities::FieldIOSharedPtr fld = MemoryManager<LibUtilities::FieldIO>::AllocateSharedPtr(vComm); //---------------------------------------------- // Read in mesh from input file SpatialDomains::MeshGraphSharedPtr graph2D = MemoryManager<SpatialDomains::MeshGraph2D>::AllocateSharedPtr(vSession); //---------------------------------------------- //---------------------------------------------- // Define Expansion int nplanes = vSession->GetParameter("HomModesZ"); lz = vSession->GetParameter("LZ"); bool useFFT = false; bool deal = false; const LibUtilities::PointsKey Pkey(nplanes,LibUtilities::eFourierEvenlySpaced); const LibUtilities::BasisKey Bkey(LibUtilities::eFourier,nplanes,Pkey); Exp = MemoryManager<MultiRegions::DisContField3DHomogeneous1D>:: AllocateSharedPtr(vSession,Bkey,lz,useFFT,deal,graph2D,vSession->GetVariable(0)); //---------------------------------------------- Timing("Read files and define exp .."); //---------------------------------------------- // Print summary of solution details factors[StdRegions::eFactorLambda] = vSession->GetParameter("Lambda"); factors[StdRegions::eFactorTau] = 1.0; const SpatialDomains::ExpansionMap &expansions = graph2D->GetExpansions(); LibUtilities::BasisKey bkey0 = expansions.begin()->second->m_basisKeyVector[0]; cout << "Solving 3D Helmholtz (Homogeneous in z-direction):" << endl; cout << " Lambda : " << factors[StdRegions::eFactorLambda] << endl; cout << " Lz : " << lz << endl; cout << " No. modes : " << bkey0.GetNumModes() << endl; cout << " No. hom. modes : " << Bkey.GetNumModes() << endl; cout << endl; //---------------------------------------------- //---------------------------------------------- // Set up coordinates of mesh for Forcing function evaluation nq = Exp->GetTotPoints(); xc0 = Array<OneD,NekDouble>(nq,0.0); xc1 = Array<OneD,NekDouble>(nq,0.0); xc2 = Array<OneD,NekDouble>(nq,0.0); Exp->GetCoords(xc0,xc1,xc2); //---------------------------------------------- //---------------------------------------------- // Define forcing function for first variable defined in file fce = Array<OneD,NekDouble>(nq); LibUtilities::EquationSharedPtr ffunc = vSession->GetFunction("Forcing", 0); ffunc->Evaluate(xc0, xc1, xc2, fce); //---------------------------------------------- //---------------------------------------------- // Setup expansion containing the forcing function Fce = MemoryManager<MultiRegions::DisContField3DHomogeneous1D>::AllocateSharedPtr(*Exp); Fce->SetPhys(fce); //---------------------------------------------- Timing("Define forcing .."); //---------------------------------------------- // Helmholtz solution taking physical forcing Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(), NullFlagList, factors); //---------------------------------------------- Timing("Helmholtz Solve .."); #ifdef TIMING for(i = 0; i < 100; ++i) { Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(), NullFlagList, factors); } Timing("100 Helmholtz Solves:... "); #endif //----------------------------------------------- // Backward Transform Solution to get solved values at Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys()); //----------------------------------------------- Timing("Backard Transform .."); //----------------------------------------------- // Write solution to file string out = meshfile.substr(0, meshfile.find_last_of(".")) + ".fld"; std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef = Exp->GetFieldDefinitions(); std::vector<std::vector<NekDouble> > FieldData(FieldDef.size()); for(i = 0; i < FieldDef.size(); ++i) { FieldDef[i]->m_fields.push_back("u"); Exp->AppendFieldData(FieldDef[i], FieldData[i]); } fld->Write(out, FieldDef, FieldData); //----------------------------------------------- //----------------------------------------------- // See if there is an exact solution, if so // evaluate and plot errors LibUtilities::EquationSharedPtr ex_sol = vSession->GetFunction("ExactSolution", 0); if(ex_sol) { //---------------------------------------------- // evaluate exact solution ex_sol->Evaluate(xc0, xc1, xc2, fce); //---------------------------------------------- //-------------------------------------------- // Calculate error Fce->SetPhys(fce); Fce->SetPhysState(true); cout << "L infinity error: " << Exp->Linf(Exp->GetPhys(), Fce->GetPhys()) << endl; cout << "L 2 error : " << Exp->L2 (Exp->GetPhys(), Fce->GetPhys()) << endl; //-------------------------------------------- } Timing("Output .."); //---------------------------------------------- return 0; }
int main(int argc, char *argv[]) { LibUtilities::SessionReaderSharedPtr vSession = LibUtilities::SessionReader::CreateInstance(argc, argv); LibUtilities::CommSharedPtr vComm = vSession->GetComm(); MultiRegions::DisContField3DSharedPtr Exp,Fce; int i, nq, coordim; Array<OneD,NekDouble> fce; Array<OneD,NekDouble> xc0,xc1,xc2; StdRegions::ConstFactorMap factors; if(argc < 2) { fprintf(stderr,"Usage: PostProcHDG3D meshfile [solntype]\n"); exit(1); } //---------------------------------------------- // Read in mesh from input file SpatialDomains::MeshGraphSharedPtr graph3D = MemoryManager<SpatialDomains::MeshGraph3D>::AllocateSharedPtr(vSession); //---------------------------------------------- //---------------------------------------------- // Print summary of solution details factors[StdRegions::eFactorLambda] = vSession->GetParameter("Lambda"); factors[StdRegions::eFactorTau] = 1.0; const SpatialDomains::ExpansionMap &expansions = graph3D->GetExpansions(); LibUtilities::BasisKey bkey0 = expansions.begin()->second->m_basisKeyVector[0]; //MAY NEED ADJUSTMENT FOR VARIOUS ELEMENT TYPES int num_modes = bkey0.GetNumModes(); int num_points = bkey0.GetNumPoints(); if (vComm->GetRank() == 0) { cout << "Solving 3D Helmholtz:" << endl; cout << " Lambda : " << factors[StdRegions::eFactorLambda] << endl; cout << " No. modes : " << num_modes << endl; cout << " No. points : " << num_points << endl; cout << endl; } //---------------------------------------------- // Define Expansion //---------------------------------------------- Exp = MemoryManager<MultiRegions::DisContField3D>:: AllocateSharedPtr(vSession,graph3D,vSession->GetVariable(0)); //---------------------------------------------- Timing("Read files and define exp .."); //---------------------------------------------- // Set up coordinates of mesh for Forcing function evaluation coordim = Exp->GetCoordim(0); nq = Exp->GetTotPoints(); xc0 = Array<OneD,NekDouble>(nq,0.0); xc1 = Array<OneD,NekDouble>(nq,0.0); xc2 = Array<OneD,NekDouble>(nq,0.0); switch(coordim) { case 1: Exp->GetCoords(xc0); break; case 2: Exp->GetCoords(xc0,xc1); break; case 3: Exp->GetCoords(xc0,xc1,xc2); break; } //---------------------------------------------- //---------------------------------------------- // Define forcing function for first variable defined in file fce = Array<OneD,NekDouble>(nq); LibUtilities::EquationSharedPtr ffunc = vSession->GetFunction("Forcing", 0); ffunc->Evaluate(xc0, xc1, xc2, fce); //---------------------------------------------- //---------------------------------------------- // Setup expansion containing the forcing function Fce = MemoryManager<MultiRegions::DisContField3D>::AllocateSharedPtr(*Exp); Fce->SetPhys(fce); //---------------------------------------------- Timing("Define forcing .."); //---------------------------------------------- // Helmholtz solution taking physical forcing Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(), NullFlagList, factors); //---------------------------------------------- Timing("Helmholtz Solve .."); //----------------------------------------------- // Backward Transform Solution to get solved values at Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys()); //----------------------------------------------- Timing("Backward Transform .."); //----------------------------------------------- // Write solution to file //string out = vSession->GetSessionName() + ".fld"; //std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef // = Exp->GetFieldDefinitions(); //std::vector<std::vector<NekDouble> > FieldData(FieldDef.size()); //for(i = 0; i < FieldDef.size(); ++i) //{ // FieldDef[i]->m_fields.push_back("u"); // Exp->AppendFieldData(FieldDef[i], FieldData[i]); //} //LibUtilities::Write(out, FieldDef, FieldData); //-------------------------------------------- //----------------------------------------------- // See if there is an exact solution, if so // evaluate and plot errors LibUtilities::EquationSharedPtr ex_sol = vSession->GetFunction("ExactSolution", 0); //---------------------------------------------- // evaluate exact solution ex_sol->Evaluate(xc0, xc1, xc2, fce); //---------------------------------------------- //Tetrahedron const LibUtilities::PointsKey PkeyT1(num_points+1,LibUtilities::eGaussLobattoLegendre); const LibUtilities::PointsKey PkeyT2(num_points,LibUtilities::eGaussRadauMAlpha1Beta0);//need to doublecheck this one const LibUtilities::PointsKey PkeyT3(num_points,LibUtilities::eGaussRadauMAlpha2Beta0);//need to doublecheck this one LibUtilities::BasisKeyVector BkeyT; BkeyT.push_back(LibUtilities::BasisKey(LibUtilities::eModified_A, num_modes+1, PkeyT1)); BkeyT.push_back(LibUtilities::BasisKey(LibUtilities::eModified_B, num_modes+1, PkeyT2)); BkeyT.push_back(LibUtilities::BasisKey(LibUtilities::eModified_C, num_modes+1, PkeyT3)); //Prism const LibUtilities::PointsKey PkeyP1(num_points+1,LibUtilities::eGaussLobattoLegendre); const LibUtilities::PointsKey PkeyP2(num_points+1,LibUtilities::eGaussLobattoLegendre); const LibUtilities::PointsKey PkeyP3(num_points,LibUtilities::eGaussRadauMAlpha1Beta0);//need to doublecheck this one LibUtilities::BasisKeyVector BkeyP; BkeyP.push_back(LibUtilities::BasisKey(LibUtilities::eModified_A, num_modes+1, PkeyP1)); BkeyP.push_back(LibUtilities::BasisKey(LibUtilities::eModified_A, num_modes+1, PkeyP2)); BkeyP.push_back(LibUtilities::BasisKey(LibUtilities::eModified_B, num_modes+1, PkeyP3)); //Hexahedron const LibUtilities::PointsKey PkeyH(num_points+1,LibUtilities::eGaussLobattoLegendre); LibUtilities::BasisKeyVector BkeyH; BkeyH.push_back(LibUtilities::BasisKey(LibUtilities::eModified_A, num_modes+1, PkeyH)); BkeyH.push_back(LibUtilities::BasisKey(LibUtilities::eModified_A, num_modes+1, PkeyH)); BkeyH.push_back(LibUtilities::BasisKey(LibUtilities::eModified_A, num_modes+1, PkeyH)); graph3D->SetBasisKey(LibUtilities::eTetrahedron, BkeyT); graph3D->SetBasisKey(LibUtilities::ePrism, BkeyP); graph3D->SetBasisKey(LibUtilities::eHexahedron, BkeyH); MultiRegions::DisContField3DSharedPtr PostProc = MemoryManager<MultiRegions::DisContField3D>::AllocateSharedPtr(vSession,graph3D,vSession->GetVariable(0)); int ErrorCoordim = PostProc->GetCoordim(0); int ErrorNq = PostProc->GetTotPoints(); Array<OneD,NekDouble> ErrorXc0(ErrorNq,0.0); Array<OneD,NekDouble> ErrorXc1(ErrorNq,0.0); Array<OneD,NekDouble> ErrorXc2(ErrorNq,0.0); switch(ErrorCoordim) { case 1: PostProc->GetCoords(ErrorXc0); break; case 2: PostProc->GetCoords(ErrorXc0,ErrorXc1); break; case 3: PostProc->GetCoords(ErrorXc0,ErrorXc1,ErrorXc2); break; } // evaluate exact solution Array<OneD,NekDouble> ppSol(ErrorNq); ex_sol->Evaluate(ErrorXc0,ErrorXc1,ErrorXc2,ppSol); // calcualte spectral/hp approximation on the quad points of this new // expansion basis std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef = Exp->GetFieldDefinitions(); std::vector<std::vector<NekDouble> > FieldData(FieldDef.size()); std::string fieldstr = "u"; for(i = 0; i < FieldDef.size(); ++i) { FieldDef[i]->m_fields.push_back(fieldstr); Exp->AppendFieldData(FieldDef[i], FieldData[i]); PostProc->ExtractDataToCoeffs(FieldDef[i],FieldData[i],fieldstr,PostProc->UpdateCoeffs()); } // Interpolation of trace std::vector<LibUtilities::FieldDefinitionsSharedPtr> TraceDef = Exp->GetTrace()->GetFieldDefinitions(); std::vector<std::vector<NekDouble> > TraceData(TraceDef.size()); for(i = 0; i < TraceDef.size(); ++i) { TraceDef[i]->m_fields.push_back(fieldstr); Exp->GetTrace()->AppendFieldData(TraceDef[i], TraceData[i]); PostProc->GetTrace()->ExtractDataToCoeffs(TraceDef[i],TraceData[i],fieldstr,PostProc->GetTrace()->UpdateCoeffs()); } PostProc->BwdTrans_IterPerExp(PostProc->GetCoeffs(),PostProc->UpdatePhys()); PostProc->EvaluateHDGPostProcessing(PostProc->UpdateCoeffs()); PostProc->BwdTrans_IterPerExp(PostProc->GetCoeffs(),PostProc->UpdatePhys()); NekDouble vLinfError = Exp->Linf(Exp->GetPhys(), fce); NekDouble vL2Error = Exp->L2 (Exp->GetPhys(), fce); NekDouble L2ErrorPostProc = PostProc->L2(PostProc->GetPhys(), ppSol); NekDouble LinfErrorPostProc = PostProc->Linf(PostProc->GetPhys(), ppSol); if (vSession->GetComm()->GetRank() == 0) { cout << "L infinity error : " << vLinfError << endl; cout << "L 2 error : " << vL2Error << endl; cout << "Postprocessed L infinity error : " << LinfErrorPostProc << endl; cout << "Postprocessed L 2 error : " << L2ErrorPostProc << endl; } vSession->Finalise(); return 0; }
int main(int argc, char *argv[]) { MultiRegions::ContField3DSharedPtr Exp,Fce,Sol; int i, nq, coordim; Array<OneD,NekDouble> fce,sol; Array<OneD,NekDouble> xc0,xc1,xc2; NekDouble lambda; vector<string> vFilenames; if(argc != 6) { fprintf(stderr,"Usage: TimingCGHelmSolve3D Type MeshSize NumModes OptimisationLevel OperatorToTest\n"); fprintf(stderr," where: - Type is one of the following:\n"); fprintf(stderr," 1: Regular Hexahedrons \n"); fprintf(stderr," 2: Deformed Hexahedrons (may not be supported) \n"); fprintf(stderr," 3: Regular Tetrahedrons \n"); fprintf(stderr," where: - MeshSize is 1/h \n"); fprintf(stderr," where: - NumModes is the number of 1D modes of the expansion \n"); fprintf(stderr," where: - OptimisationLevel is one of the following:\n"); fprintf(stderr," 0: Use elemental sum-factorisation evaluation \n"); fprintf(stderr," 2: Use elemental matrix evaluation using blockmatrices \n"); fprintf(stderr," 3: Use global matrix evaluation \n"); fprintf(stderr," 4: Use optimal evaluation (this option requires optimisation-files being set-up) \n"); fprintf(stderr," where: - OperatorToTest is one of the following:\n"); fprintf(stderr," 0: BwdTrans \n"); fprintf(stderr," 1: Inner Product \n"); fprintf(stderr," 2: Mass Matrix \n"); exit(1); } boost::filesystem::path basePath(BASE_PATH); int Type = atoi(argv[1]); int MeshSize = atoi(argv[2]); int NumModes = atoi(argv[3]); int optLevel = atoi(argv[4]); int opToTest = atoi(argv[5]); //---------------------------------------------- // Retrieve the necessary input files stringstream MeshFileName; stringstream MeshFileDirectory; stringstream BCfileName; stringstream ExpansionsFileName; stringstream GlobOptFileName; switch(Type) { case 1: { MeshFileDirectory << "RegularHexMeshes"; MeshFileName << "UnitCube_RegularHexMesh_h_1_" << MeshSize << ".xml"; } break; case 2: { MeshFileDirectory << "DeformedHexMeshes"; MeshFileName << "UnitCube_DeformedHexMesh_h_1_" << MeshSize << ".xml"; } break; case 3: { MeshFileDirectory << "RegularTetMeshes"; MeshFileName << "UnitCube_RegularTetMesh_h_1_" << MeshSize << ".xml"; } break; default: { cerr << "Type should be equal to one of the following values: "<< endl; cerr << " 1: Regular Hexahedrons" << endl; cerr << " 2: Deformed Hexahedrons" << endl; cerr << " 3: Regular Tetrahedrons" << endl; exit(1); } } BCfileName << "UnitCube_DirichletBoundaryConditions.xml"; ExpansionsFileName << "NektarExpansionsNummodes" << NumModes << ".xml"; switch(optLevel) { case 0: { GlobOptFileName << "NoGlobalMat.xml"; } break; case 2: { GlobOptFileName << "DoBlockMat.xml"; } break; case 3: { GlobOptFileName << "DoGlobalMat.xml"; } break; case 4: { ASSERTL0(false,"Optimisation level not set up"); } break; default: { ASSERTL0(false,"Unrecognised optimisation level"); } } boost::filesystem::path MeshFilePath = basePath / boost::filesystem::path("InputFiles") / boost::filesystem::path("Geometry") / boost::filesystem::path(MeshFileDirectory.str()) / boost::filesystem::path(MeshFileName.str()); vFilenames.push_back(PortablePath(MeshFilePath)); boost::filesystem::path BCfilePath = basePath / boost::filesystem::path("InputFiles") / boost::filesystem::path("Conditions") / boost::filesystem::path(BCfileName.str()); vFilenames.push_back(PortablePath(BCfilePath)); boost::filesystem::path ExpansionsFilePath = basePath / boost::filesystem::path("InputFiles") / boost::filesystem::path("Expansions") / boost::filesystem::path(ExpansionsFileName.str()); vFilenames.push_back(PortablePath(ExpansionsFilePath)); boost::filesystem::path GlobOptFilePath = basePath / boost::filesystem::path("InputFiles") / boost::filesystem::path("Optimisation") / boost::filesystem::path(GlobOptFileName.str()); vFilenames.push_back(PortablePath(GlobOptFilePath)); //---------------------------------------------- StdRegions::MatrixType type; switch (opToTest) { case 0: type = StdRegions::eBwdTrans; break; case 1: type = StdRegions::eIProductWRTBase; break; case 2: type = StdRegions::eMass; break; case 3: type = StdRegions::eHelmholtz; break; default: cout << "Operator " << opToTest << " not defined." << endl; } LibUtilities::SessionReaderSharedPtr vSession = LibUtilities::SessionReader::CreateInstance(argc, argv, vFilenames); //---------------------------------------------- // Read in mesh from input file SpatialDomains::MeshGraphSharedPtr graph3D = MemoryManager<SpatialDomains::MeshGraph3D>::AllocateSharedPtr(vSession); //---------------------------------------------- //---------------------------------------------- // Print summary of solution details lambda = vSession->GetParameter("Lambda"); //---------------------------------------------- //---------------------------------------------- // Define Expansion Exp = MemoryManager<MultiRegions::ContField3D> ::AllocateSharedPtr(vSession, graph3D, vSession->GetVariable(0)); //---------------------------------------------- int NumElements = Exp->GetExpSize(); //---------------------------------------------- // Set up coordinates of mesh for Forcing function evaluation coordim = Exp->GetCoordim(0); nq = Exp->GetTotPoints(); xc0 = Array<OneD,NekDouble>(nq,0.0); xc1 = Array<OneD,NekDouble>(nq,0.0); xc2 = Array<OneD,NekDouble>(nq,0.0); switch(coordim) { case 1: Exp->GetCoords(xc0); break; case 2: Exp->GetCoords(xc0,xc1); break; case 3: Exp->GetCoords(xc0,xc1,xc2); break; } //---------------------------------------------- //---------------------------------------------- // Define forcing function for first variable defined in file fce = Array<OneD,NekDouble>(nq); LibUtilities::EquationSharedPtr ffunc = vSession->GetFunction("Forcing",0); for(i = 0; i < nq; ++i) { fce[i] = ffunc->Evaluate(xc0[i],xc1[i],xc2[i]); } //---------------------------------------------- //---------------------------------------------- // Setup expansion containing the forcing function Fce = MemoryManager<MultiRegions::ContField3D>::AllocateSharedPtr(*Exp); Fce->SetPhys(fce); //---------------------------------------------- //---------------------------------------------- // See if there is an exact solution, if so // evaluate and plot errors LibUtilities::EquationSharedPtr ex_sol = vSession->GetFunction("ExactSolution",0); //---------------------------------------------- // evaluate exact solution sol = Array<OneD,NekDouble>(nq); for(i = 0; i < nq; ++i) { sol[i] = ex_sol->Evaluate(xc0[i],xc1[i],xc2[i]); } Sol = MemoryManager<MultiRegions::ContField3D>::AllocateSharedPtr(*Exp); Sol->SetPhys(sol); Sol->SetPhysState(true); //---------------------------------------------- NekDouble L2Error; NekDouble LinfError; if (type == StdRegions::eHelmholtz) { FlagList flags; flags.set(eUseGlobal, true); StdRegions::ConstFactorMap factors; factors[StdRegions::eFactorLambda] = lambda; //---------------------------------------------- // Helmholtz solution taking physical forcing Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(),flags,factors); // GeneralMatrixOp does not impose boundary conditions. // MultiRegions::GlobalMatrixKey key(type, lambda, Exp->GetLocalToGlobalMap()); // Exp->GeneralMatrixOp (key, Fce->GetPhys(),Exp->UpdateContCoeffs(), true); //---------------------------------------------- //---------------------------------------------- // Backward Transform Solution to get solved values at Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys(), MultiRegions::eGlobal); //---------------------------------------------- L2Error = Exp->L2 (Sol->GetPhys()); LinfError = Exp->Linf(Sol->GetPhys()); } else { Exp->FwdTrans(Sol->GetPhys(), Exp->UpdateCoeffs(), MultiRegions::eGlobal); //---------------------------------------------- // Backward Transform Solution to get solved values at Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys(), MultiRegions::eGlobal); //---------------------------------------------- L2Error = Exp->L2 (Sol->GetPhys()); LinfError = Exp->Linf(Sol->GetPhys()); } //-------------------------------------------- // alternative error calculation /* const LibUtilities::PointsKey PkeyT1(30,LibUtilities::eGaussLobattoLegendre); const LibUtilities::PointsKey PkeyT2(30,LibUtilities::eGaussRadauMAlpha1Beta0); const LibUtilities::PointsKey PkeyQ1(30,LibUtilities::eGaussLobattoLegendre); const LibUtilities::PointsKey PkeyQ2(30,LibUtilities::eGaussLobattoLegendre); const LibUtilities::BasisKey BkeyT1(LibUtilities::eModified_A,NumModes,PkeyT1); const LibUtilities::BasisKey BkeyT2(LibUtilities::eModified_B,NumModes,PkeyT2); const LibUtilities::BasisKey BkeyQ1(LibUtilities::eModified_A,NumModes,PkeyQ1); const LibUtilities::BasisKey BkeyQ2(LibUtilities::eModified_A,NumModes,PkeyQ2); MultiRegions::ExpList3DSharedPtr ErrorExp = MemoryManager<MultiRegions::ExpList3D>::AllocateSharedPtr(BkeyT1,BkeyT2,BkeyT3,BkeyQ1,BkeyQ2,BkeyQ3,graph3D); int ErrorCoordim = ErrorExp->GetCoordim(0); int ErrorNq = ErrorExp->GetTotPoints(); Array<OneD,NekDouble> ErrorXc0(ErrorNq,0.0); Array<OneD,NekDouble> ErrorXc1(ErrorNq,0.0); Array<OneD,NekDouble> ErrorXc2(ErrorNq,0.0); switch(ErrorCoordim) { case 1: ErrorExp->GetCoords(ErrorXc0); break; case 2: ErrorExp->GetCoords(ErrorXc0,ErrorXc1); break; case 3: ErrorExp->GetCoords(ErrorXc0,ErrorXc1,ErrorXc2); break; } // evaluate exact solution Array<OneD,NekDouble> ErrorSol(ErrorNq); for(i = 0; i < ErrorNq; ++i) { ErrorSol[i] = ex_sol->Evaluate(ErrorXc0[i],ErrorXc1[i],ErrorXc2[i]); } // calcualte spectral/hp approximation on the quad points of this new // expansion basis Exp->GlobalToLocal(Exp->GetContCoeffs(),ErrorExp->UpdateCoeffs()); ErrorExp->BwdTrans_IterPerExp(ErrorExp->GetCoeffs(),ErrorExp->UpdatePhys()); NekDouble L2ErrorBis = ErrorExp->L2 (ErrorSol); NekDouble LinfErrorBis = ErrorExp->Linf(ErrorSol); */ //-------------------------------------------- #if 0 cout << "L infinity error: " << LinfErrorBis << endl; cout << "L 2 error: " << L2ErrorBis << endl; #endif //---------------------------------------------- NekDouble exeTime; int NumCalls; exeTime = TimeMatrixOp(type, Exp, Fce, NumCalls, lambda); int nLocCoeffs = Exp->GetLocalToGlobalMap()->GetNumLocalCoeffs(); int nGlobCoeffs = Exp->GetLocalToGlobalMap()->GetNumGlobalCoeffs(); int nLocBndCoeffs = Exp->GetLocalToGlobalMap()->GetNumLocalBndCoeffs(); int nGlobBndCoeffs = Exp->GetLocalToGlobalMap()->GetNumGlobalBndCoeffs(); int nLocDirCoeffs = Exp->GetLocalToGlobalMap()->GetNumLocalDirBndCoeffs(); int nGlobDirCoeffs = Exp->GetLocalToGlobalMap()->GetNumGlobalDirBndCoeffs(); // MultiRegions::GlobalMatrixKey key(StdRegions::eHelmholtz,lambda,Exp->GetLocalToGlobalMap()); // int nnz = Exp->GetGlobalMatrixNnz(key); ostream &outfile = cout; outfile.precision(0); outfile << setw(10) << Type << " "; outfile << setw(10) << NumElements << " "; outfile << setw(10) << NumModes << " "; outfile << setw(10) << NumCalls << " "; outfile << setw(10) << fixed << noshowpoint << exeTime << " "; outfile << setw(10) << fixed << noshowpoint << ((NekDouble) (exeTime/((NekDouble)NumCalls))) << " "; outfile.precision(7); outfile << setw(15) << scientific << noshowpoint << L2Error << " "; outfile << setw(15) << scientific << noshowpoint << "- "; // << L2ErrorBis << " "; outfile << setw(15) << scientific << noshowpoint << LinfError << " "; outfile << setw(15) << scientific << noshowpoint << "- ";// << LinfErrorBis << " "; outfile << setw(10) << nLocCoeffs << " "; outfile << setw(10) << nGlobCoeffs << " "; outfile << setw(10) << nLocBndCoeffs << " "; outfile << setw(10) << nGlobBndCoeffs << " "; outfile << setw(10) << nLocDirCoeffs << " "; outfile << setw(10) << nGlobDirCoeffs << " "; outfile << setw(10) << "- "; // << nnz << " "; outfile << setw(10) << optLevel << " "; outfile << endl; //---------------------------------------------- return 0; }
int main(int argc, char *argv[]) { LibUtilities::SessionReaderSharedPtr vSession = LibUtilities::SessionReader::CreateInstance(argc, argv); LibUtilities::CommSharedPtr vComm = vSession->GetComm(); MultiRegions::DisContField3DSharedPtr Exp, Fce; int i, nq, coordim; Array<OneD,NekDouble> fce; Array<OneD,NekDouble> xc0,xc1,xc2; StdRegions::ConstFactorMap factors; if(argc < 2) { fprintf(stderr,"Usage: HDGHelmholtz3D meshfile [solntype]\n"); exit(1); } LibUtilities::FieldIOSharedPtr fld = MemoryManager<LibUtilities::FieldIO>::AllocateSharedPtr(vComm); //---------------------------------------------- // Read in mesh from input file SpatialDomains::MeshGraphSharedPtr graph3D = MemoryManager<SpatialDomains::MeshGraph3D>::AllocateSharedPtr(vSession); //---------------------------------------------- //---------------------------------------------- // Print summary of solution details factors[StdRegions::eFactorLambda] = vSession->GetParameter("Lambda"); factors[StdRegions::eFactorTau] = 1.0; const SpatialDomains::ExpansionMap &expansions = graph3D->GetExpansions(); LibUtilities::BasisKey bkey0 = expansions.begin()->second->m_basisKeyVector[0]; if (vComm->GetRank() == 0) { cout << "Solving 3D Helmholtz:" << endl; cout << " - Communication: " << vSession->GetComm()->GetType() << " (" << vSession->GetComm()->GetSize() << " processes)" << endl; cout << " - Solver type : " << vSession->GetSolverInfo("GlobalSysSoln") << endl; cout << " - Lambda : " << factors[StdRegions::eFactorLambda] << endl; cout << " - No. modes : " << bkey0.GetNumModes() << endl; cout << endl; } //---------------------------------------------- //---------------------------------------------- // Define Expansion Exp = MemoryManager<MultiRegions::DisContField3D>:: AllocateSharedPtr(vSession,graph3D,vSession->GetVariable(0)); //---------------------------------------------- Timing("Read files and define exp .."); //---------------------------------------------- // Set up coordinates of mesh for Forcing function evaluation coordim = Exp->GetCoordim(0); nq = Exp->GetTotPoints(); xc0 = Array<OneD,NekDouble>(nq,0.0); xc1 = Array<OneD,NekDouble>(nq,0.0); xc2 = Array<OneD,NekDouble>(nq,0.0); switch(coordim) { case 1: Exp->GetCoords(xc0); break; case 2: Exp->GetCoords(xc0,xc1); break; case 3: Exp->GetCoords(xc0,xc1,xc2); break; } //---------------------------------------------- //---------------------------------------------- // Define forcing function for first variable defined in file fce = Array<OneD,NekDouble>(nq); LibUtilities::EquationSharedPtr ffunc = vSession->GetFunction("Forcing", 0); ffunc->Evaluate(xc0, xc1, xc2, fce); //---------------------------------------------- //---------------------------------------------- // Setup expansion containing the forcing function Fce = MemoryManager<MultiRegions::DisContField3D>::AllocateSharedPtr(*Exp); Fce->SetPhys(fce); //---------------------------------------------- Timing("Define forcing .."); //---------------------------------------------- // Helmholtz solution taking physical forcing Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(), NullFlagList, factors); //---------------------------------------------- Timing("Helmholtz Solve .."); #if 0 for(i = 0; i < 100; ++i) { Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(), NullFlagList, factors); } Timing("100 Helmholtz Solves:... "); #endif //---------------------------------------------- // Backward Transform Solution to get solved values at Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys()); //---------------------------------------------- Timing("Backward Transform .."); //----------------------------------------------- // Write solution to file string out = vSession->GetSessionName() + ".fld"; std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef = Exp->GetFieldDefinitions(); std::vector<std::vector<NekDouble> > FieldData(FieldDef.size()); for(i = 0; i < FieldDef.size(); ++i) { FieldDef[i]->m_fields.push_back("u"); Exp->AppendFieldData(FieldDef[i], FieldData[i]); } fld->Write(out, FieldDef, FieldData); //----------------------------------------------- //---------------------------------------------- // See if there is an exact solution, if so // evaluate and plot errors LibUtilities::EquationSharedPtr ex_sol = vSession->GetFunction("ExactSolution", 0); if(ex_sol) { //---------------------------------------------- // evaluate exact solution ex_sol->Evaluate(xc0, xc1, xc2, fce); //---------------------------------------------- //-------------------------------------------- // Calculate L_inf error Fce->SetPhys(fce); Fce->SetPhysState(true); NekDouble vLinfError = Exp->Linf(Exp->GetPhys(), Fce->GetPhys()); NekDouble vL2Error = Exp->L2 (Exp->GetPhys(), Fce->GetPhys()); NekDouble vH1Error = Exp->H1 (Exp->GetPhys(), Fce->GetPhys()); if (vComm->GetRank() == 0) { cout << "L infinity error: " << vLinfError << endl; cout << "L 2 error : " << vL2Error << endl; cout << "H 1 error : " << vH1Error << endl; } //-------------------------------------------- } Timing("Output .."); //---------------------------------------------- vSession->Finalise(); return 0; }
int main(int argc, char *argv[]) { LibUtilities::SessionReaderSharedPtr vSession = LibUtilities::SessionReader::CreateInstance(argc, argv); LibUtilities::CommSharedPtr vComm = vSession->GetComm(); MultiRegions::ContField1DSharedPtr Exp,Fce; int i, nq, coordim; Array<OneD,NekDouble> fce; Array<OneD,NekDouble> xc0,xc1,xc2; StdRegions::ConstFactorMap factors; if( (argc != 2) && (argc != 3) && (argc != 4)) { fprintf(stderr,"Usage: Helmholtz1D meshfile \n"); exit(1); } try { LibUtilities::FieldIOSharedPtr fld = MemoryManager<LibUtilities::FieldIO>::AllocateSharedPtr(vComm); //---------------------------------------------- // Read in mesh from input file SpatialDomains::MeshGraphSharedPtr graph1D = SpatialDomains::MeshGraph::Read(vSession); //---------------------------------------------- //---------------------------------------------- // Print summary of solution details factors[StdRegions::eFactorLambda] = vSession->GetParameter("Lambda"); const SpatialDomains::ExpansionMap &expansions = graph1D->GetExpansions(); LibUtilities::BasisKey bkey0 = expansions.begin()->second->m_basisKeyVector[0]; if (vComm->GetRank() ==0) { cout << "Solving 1D Helmholtz: " << endl; cout << " Communication: " << vComm->GetType() << endl; cout << " Solver type : " << vSession->GetSolverInfo("GlobalSysSoln") << endl; cout << " Lambda : " << factors[StdRegions::eFactorLambda] << endl; cout << " No. modes : " << bkey0.GetNumModes() << endl; } //---------------------------------------------- //---------------------------------------------- // Define Expansion Exp = MemoryManager<MultiRegions::ContField1D>:: AllocateSharedPtr(vSession,graph1D,vSession->GetVariable(0)); //---------------------------------------------- //---------------------------------------------- // Set up coordinates of mesh for Forcing function evaluation coordim = Exp->GetCoordim(0); nq = Exp->GetTotPoints(); xc0 = Array<OneD,NekDouble>(nq); xc1 = Array<OneD,NekDouble>(nq); xc2 = Array<OneD,NekDouble>(nq); switch(coordim) { case 1: Exp->GetCoords(xc0); Vmath::Zero(nq,&xc1[0],1); Vmath::Zero(nq,&xc2[0],1); break; case 2: Exp->GetCoords(xc0,xc1); Vmath::Zero(nq,&xc2[0],1); break; case 3: Exp->GetCoords(xc0,xc1,xc2); break; } //---------------------------------------------- //---------------------------------------------- // Define forcing function for first variable defined in file fce = Array<OneD,NekDouble>(nq); LibUtilities::EquationSharedPtr ffunc = vSession->GetFunction("Forcing", 0); ffunc->Evaluate(xc0,xc1,xc2, fce); //---------------------------------------------- //---------------------------------------------- // Setup expansion containing the forcing function Fce = MemoryManager<MultiRegions::ContField1D>::AllocateSharedPtr(*Exp); Fce->SetPhys(fce); //---------------------------------------------- //---------------------------------------------- //Helmholtz solution taking physical forcing after setting //initial condition to zero Vmath::Zero(Exp->GetNcoeffs(),Exp->UpdateCoeffs(),1); Exp->HelmSolve(Fce->GetPhys(), Exp->UpdateCoeffs(), NullFlagList, factors); //---------------------------------------------- //---------------------------------------------- // Backward Transform Solution to get solved values at Exp->BwdTrans(Exp->GetCoeffs(), Exp->UpdatePhys()); //---------------------------------------------- //---------------------------------------------- // Write solution string out(strtok(argv[1],".")); string endfile(".fld"); out += endfile; std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef = Exp->GetFieldDefinitions(); std::vector<std::vector<NekDouble> > FieldData(FieldDef.size()); for(i = 0; i < FieldDef.size(); ++i) { FieldDef[i]->m_fields.push_back("u"); Exp->AppendFieldData(FieldDef[i], FieldData[i]); } fld->Write(out, FieldDef, FieldData); //---------------------------------------------- //---------------------------------------------- // See if there is an exact solution, if so // evaluate and plot errors LibUtilities::EquationSharedPtr ex_sol = vSession->GetFunction("ExactSolution", 0); if(ex_sol) { //---------------------------------------------- // evaluate exact solution ex_sol->Evaluate(xc0,xc1,xc2, fce); Fce->SetPhys(fce); //---------------------------------------------- //-------------------------------------------- // Calculate errors NekDouble vLinfError = Exp->Linf(Exp->GetPhys(), Fce->GetPhys()); NekDouble vL2Error = Exp->L2(Exp->GetPhys(), Fce->GetPhys()); NekDouble vH1Error = Exp->H1(Exp->GetPhys(), Fce->GetPhys()); if (vComm->GetRank() == 0) { cout << "L infinity error: " << vLinfError << endl; cout << "L 2 error: " << vL2Error << endl; cout << "H 1 error: " << vH1Error << endl; } //-------------------------------------------- } //---------------------------------------------- } catch (const std::runtime_error&) { cerr << "Caught exception." << endl; return 1; } vComm->Finalise(); return 0; }