void AdvanceSolution_Midpoint(Conserved *U, double dt) { int i; Conserved *L = (Conserved*) malloc((Nx+2*Ng)*sizeof(Conserved)); Conserved *U1 = (Conserved*) malloc((Nx+2*Ng)*sizeof(Conserved)); SetBoundaryConditions(U); TimeDerivative(U, L); for (i=0; i<Nx+2*Ng; ++i) { U1[i].D = U[i].D + L[i].D * 0.5 * dt; U1[i].tau = U[i].tau + L[i].tau * 0.5 * dt; U1[i].Sx = U[i].Sx + L[i].Sx * 0.5 * dt; U1[i].Sy = U[i].Sy + L[i].Sy * 0.5 * dt; U1[i].Sz = U[i].Sz + L[i].Sz * 0.5 * dt; } SetBoundaryConditions(U1); TimeDerivative(U1, L); for (i=0; i<Nx+2*Ng; ++i) { U[i].D = U[i].D + L[i].D * dt; U[i].tau = U[i].tau + L[i].tau * dt; U[i].Sx = U[i].Sx + L[i].Sx * dt; U[i].Sy = U[i].Sy + L[i].Sy * dt; U[i].Sz = U[i].Sz + L[i].Sz * dt; } free(L); free(U1); }
/** * Implicit part of the method - Poisson + nConv*Helmholtz */ void VelocityCorrectionScheme::SolveUnsteadyStokesSystem( const Array<OneD, const Array<OneD, NekDouble> > &inarray, Array<OneD, Array<OneD, NekDouble> > &outarray, const NekDouble time, const NekDouble aii_Dt) { int i; int phystot = m_fields[0]->GetTotPoints(); Array<OneD, Array< OneD, NekDouble> > F(m_nConvectiveFields); for(i = 0; i < m_nConvectiveFields; ++i) { F[i] = Array<OneD, NekDouble> (phystot, 0.0); } // Enforcing boundary conditions on all fields SetBoundaryConditions(time); // Substep the pressure boundary condition if using substepping m_extrapolation->SubStepSetPressureBCs(inarray,aii_Dt,m_kinvis); // Set up forcing term for pressure Poisson equation SetUpPressureForcing(inarray, F, aii_Dt); // Solve Pressure System SolvePressure (F[0]); // Set up forcing term for Helmholtz problems SetUpViscousForcing(inarray, F, aii_Dt); // Solve velocity system SolveViscous( F, outarray, aii_Dt); }
void EulerADCFE::DoOdeProjection( const Array<OneD, const Array<OneD, NekDouble> > &inarray, Array<OneD, Array<OneD, NekDouble> > &outarray, const NekDouble time) { int i; int nvariables = inarray.num_elements(); switch(m_projectionType) { case MultiRegions::eDiscontinuous: { // Just copy over array int npoints = GetNpoints(); for(i = 0; i < nvariables; ++i) { Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1); } SetBoundaryConditions(outarray, time); break; } case MultiRegions::eGalerkin: case MultiRegions::eMixed_CG_Discontinuous: { ASSERTL0(false, "No Continuous Galerkin for Euler equations"); break; } default: ASSERTL0(false, "Unknown projection scheme"); break; } }
/** * Does the projection between ... space and the ... space. Also checks for Q-inflow boundary * conditions at the inflow of the current arterial segment and applies the Q-inflow if specified */ void PulseWavePropagation::SetPulseWaveBoundaryConditions( const Array<OneD,const Array<OneD, NekDouble> >&inarray, Array<OneD, Array<OneD, NekDouble> >&outarray, const NekDouble time) { int omega; Array<OneD, MultiRegions::ExpListSharedPtr> vessel(2); int offset=0; //This will be moved to the RCR boundary condition once factory is setup if (time == 0) { m_Boundary = Array<OneD,PulseWaveBoundarySharedPtr>(2*m_nDomains); for(omega = 0; omega < m_nDomains; ++omega) { vessel[0] = m_vessels[2*omega]; for(int j = 0; j < 2; ++j) { std::string BCType =vessel[0]->GetBndConditions()[j]->GetUserDefined(); if(BCType.empty()) // if not condition given define it to be NoUserDefined { BCType = "NoUserDefined"; } m_Boundary[2*omega+j]=GetBoundaryFactory().CreateInstance(BCType,m_vessels,m_session,m_pressureArea); // turn on time depedent BCs if(BCType == "Q-inflow") { vessel[0]->GetBndConditions()[j]->SetIsTimeDependent(true); } else if(BCType == "RCR-terminal") { vessel[0]->GetBndConditions()[j]->SetIsTimeDependent(true); } } } } SetBoundaryConditions(time); // Loop over all vessesls and set boundary conditions for(omega = 0; omega < m_nDomains; ++omega) { for(int n = 0; n < 2; ++n) { m_Boundary[2*omega+n]->DoBoundary(inarray,m_A_0,m_beta,time,omega,offset,n); } offset += m_vessels[2*omega]->GetTotPoints(); } }
void AdvanceSolution_ShuOsher(Conserved *U, double dt) { int i; Conserved *L = (Conserved*) malloc((Nx+2*Ng)*sizeof(Conserved)); Conserved *U1 = (Conserved*) malloc((Nx+2*Ng)*sizeof(Conserved)); SetBoundaryConditions(U); TimeDerivative(U, L); for (i=0; i<Nx+2*Ng; ++i) { U1[i].D = U[i].D + L[i].D * dt; U1[i].tau = U[i].tau + L[i].tau * dt; U1[i].Sx = U[i].Sx + L[i].Sx * dt; U1[i].Sy = U[i].Sy + L[i].Sy * dt; U1[i].Sz = U[i].Sz + L[i].Sz * dt; } SetBoundaryConditions(U1); TimeDerivative(U1, L); for (i=0; i<Nx+2*Ng; ++i) { U1[i].D = 3./4. * U[i].D + 1./4. * U1[i].D + 1./4. * L[i].D * dt; U1[i].tau = 3./4. * U[i].tau + 1./4. * U1[i].tau + 1./4. * L[i].tau * dt; U1[i].Sx = 3./4. * U[i].Sx + 1./4. * U1[i].Sx + 1./4. * L[i].Sx * dt; U1[i].Sy = 3./4. * U[i].Sy + 1./4. * U1[i].Sy + 1./4. * L[i].Sy * dt; U1[i].Sz = 3./4. * U[i].Sz + 1./4. * U1[i].Sz + 1./4. * L[i].Sz * dt; } SetBoundaryConditions(U1); TimeDerivative(U1, L); for (i=0; i<Nx+2*Ng; ++i) { U[i].D = 1./3. * U[i].D + 2./3. * U1[i].D + 2./3. * L[i].D * dt; U[i].tau = 1./3. * U[i].tau + 2./3. * U1[i].tau + 2./3. * L[i].tau * dt; U[i].Sx = 1./3. * U[i].Sx + 2./3. * U1[i].Sx + 2./3. * L[i].Sx * dt; U[i].Sy = 1./3. * U[i].Sy + 2./3. * U1[i].Sy + 2./3. * L[i].Sy * dt; U[i].Sz = 1./3. * U[i].Sz + 2./3. * U1[i].Sz + 2./3. * L[i].Sz * dt; } free(L); free(U1); }
/** * @brief Compute the projection for the linear advection equation. * * @param inarray Given fields. * @param outarray Calculated solution. * @param time Time. */ void UnsteadyAdvection::DoOdeProjection( const Array<OneD, const Array<OneD, NekDouble> >&inarray, Array<OneD, Array<OneD, NekDouble> >&outarray, const NekDouble time) { // Counter variable int i; // Number of fields (variables of the problem) int nVariables = inarray.num_elements(); // Set the boundary conditions SetBoundaryConditions(time); // Switch on the projection type (Discontinuous or Continuous) switch(m_projectionType) { // Discontinuous projection case MultiRegions::eDiscontinuous: { // Number of quadrature points int nQuadraturePts = GetNpoints(); // Just copy over array for(i = 0; i < nVariables; ++i) { Vmath::Vcopy(nQuadraturePts, inarray[i], 1, outarray[i], 1); } break; } // Continuous projection case MultiRegions::eGalerkin: case MultiRegions::eMixed_CG_Discontinuous: { Array<OneD, NekDouble> coeffs(m_fields[0]->GetNcoeffs(),0.0); for(i = 0; i < nVariables; ++i) { m_fields[i]->FwdTrans(inarray[i], coeffs); m_fields[i]->BwdTrans_IterPerExp(coeffs, outarray[i]); } break; } default: ASSERTL0(false,"Unknown projection scheme"); break; } }
/** * @brief Compute the projection and call the method for imposing the * boundary conditions in case of discontinuous projection. */ void APE::DoOdeProjection(const Array<OneD, const Array<OneD, NekDouble> >&inarray, Array<OneD, Array<OneD, NekDouble> >&outarray, const NekDouble time) { int nvariables = inarray.num_elements(); int nq = m_fields[0]->GetNpoints(); // deep copy for (int i = 0; i < nvariables; ++i) { Vmath::Vcopy(nq, inarray[i], 1, outarray[i], 1); } SetBoundaryConditions(outarray, time); }
void AdvanceSolution_FwdEuler(Conserved *U, double dt) { int i; Conserved *L = (Conserved*) malloc((Nx+2*Ng)*sizeof(Conserved)); SetBoundaryConditions(U); TimeDerivative(U, L); for (i=0; i<Nx+2*Ng; ++i) { U[i].D += L[i].D * dt; U[i].tau += L[i].tau * dt; U[i].Sx += L[i].Sx * dt; U[i].Sy += L[i].Sy * dt; U[i].Sz += L[i].Sz * dt; } free(L); }
void VelocityCorrectionScheme::v_DoInitialise(void) { UnsteadySystem::v_DoInitialise(); // Set up Field Meta Data for output files m_fieldMetaDataMap["Kinvis"] = boost::lexical_cast<std::string>(m_kinvis); m_fieldMetaDataMap["TimeStep"] = boost::lexical_cast<std::string>(m_timestep); // set boundary conditions here so that any normal component // correction are imposed before they are imposed on intiial // field below SetBoundaryConditions(m_time); for(int i = 0; i < m_nConvectiveFields; ++i) { m_fields[i]->LocalToGlobal(); m_fields[i]->ImposeDirichletConditions(m_fields[i]->UpdateCoeffs()); m_fields[i]->GlobalToLocal(); m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(), m_fields[i]->UpdatePhys()); } }