Field* Field::Clone(int empire_id) const { Visibility vis = GetUniverse().GetObjectVisibilityByEmpire(this->ID(), empire_id); if (!(vis >= VIS_BASIC_VISIBILITY && vis <= VIS_FULL_VISIBILITY)) return 0; Field* retval = new Field(); retval->Copy(TemporaryFromThis(), empire_id); return retval; }
void TwoLayerSW::Solve( Field* velTopPrev, Field* velBotPrev, Field* etaIntPrev ) { Field* velTopTemp = NULL; Field* velBotTemp = NULL; Field* etaIntTemp = NULL; if( velTopPrev != NULL && velBotPrev != NULL && etaIntPrev != NULL ) { if( ass2 == false ) { MatDestroy( PS ); MatDestroy( PI ); MatDestroy( UI ); MatDestroy( VI ); AssembleMatrices( 1.5 ); ass2 = true; } velTopTemp = new Field( "vel-top-temp", velTop->mesh, 2, NULL ); velBotTemp = new Field( "vel-bot-temp", velBot->mesh, 2, NULL ); etaIntTemp = new Field( "eta-int-temp", etaInt->mesh, 1, NULL ); velTopTemp->Copy( velTop ); velBotTemp->Copy( velBot ); etaIntTemp->Copy( etaInt ); SolveSecondOrder( velTopPrev, velBotPrev, etaIntPrev ); velTopPrev->Copy( velTopTemp ); velBotPrev->Copy( velBotTemp ); etaIntPrev->Copy( etaIntTemp ); delete velTopTemp; delete velBotTemp; delete etaIntTemp; } else { if( ass1 == false ) { AssembleMatrices( 1.0 ); ass1 = true; } SolveFirstOrder(); } }
int main( int argc, char** argv ) { char tag[] = "petsc"; int N = 5; int nx[2] = { 80, 20 }; double min[2] = { 0.0, 0.0 }; double max[2] = { 4.0, 1.0 }; bool periodic[2] = { true, false }; Mesh* mesh = new Mesh( "mesh", nx, "legendre", N, min, max, periodic ); BCs* bcs = new BCs( true, true, false, false, mesh, 0 ); Field* omega = new Field( "omega", mesh, 1, bcs ); Field* psi = new Field( "psi", mesh, 1, bcs ); Field* vel = new Field( "vel", mesh, 2, NULL ); Field* prevOmega = new Field( "prevOmega", mesh, 1, bcs ); Field* prevVel = new Field( "prevVel", mesh, 2, NULL ); Field* fields[3]; double dt = 1000.0*pow( ((max[0] - min[0])/nx[0])/N, ((double)(N + 1))/(2 + 1)); double time = 0.0; int nTimeSteps = 10000; int timeStep_i; int dumpEvery = 25; Advector* advector; PoissonEqn* poisson; PetscInitialize( &argc, &argv, (char*)0, tag ); /* initial and boundary conditions */ omega->SetICFunc( 0, omegaIC ); psi->SetBCConst( "bottom", 0, -0.9577277 ); psi->SetBCConst( "top", 0, -0.9577277 ); /* initial solve for psi */ poisson = new PoissonEqn( psi, omega ); poisson->Solve(); psi->PeriodicUpdate(); delete poisson; GetVel( psi, vel ); /* write the initial fields to file */ WriteXDMFHeader( 0 ); fields[0] = omega; fields[1] = psi; fields[2] = vel; WriteXDMF( fields, 3, 0, time, 0.0 ); WriteXDMFFooter( 0 ); prevOmega->Copy( omega ); prevVel->Copy( vel ); for( timeStep_i = 1; timeStep_i <= nTimeSteps; timeStep_i++ ) { time += dt; cout << "time step: " << timeStep_i << ", time: " << time << ", dt: " << dt << endl; /* s-L advect omega */ advector = new Advector( omega, vel, prevOmega, prevVel ); advector->Advect( dt ); prevOmega->Copy( omega ); UpdateOmega( omega, advector->fieldSL, advector->fieldSLMinusOne ); delete advector; /* solve the eliptic equation */ poisson = new PoissonEqn( psi, omega ); poisson->Solve(); psi->PeriodicUpdate(); prevVel->Copy( vel ); GetVel( psi, vel ); delete poisson; if( timeStep_i%dumpEvery == 0 ) { WriteXDMFHeader( timeStep_i ); WriteXDMF( fields, 3, timeStep_i, time, dt ); WriteXDMFFooter( timeStep_i ); } } PetscFinalize(); delete prevVel; delete prevOmega; delete vel; delete psi; delete omega; delete bcs; delete mesh; return 0; }
int main( int argc, char** argv ) { char tag[] = "petsc"; int N = 8; int nx[2] = { 24, 12 }; double min[2] = { -2.0*M_PI, -M_PI }; double max[2] = { +2.0*M_PI, +M_PI }; bool periodic[2] = { true, false }; Mesh* vMesh = new Mesh( "vMesh", nx, "legendre", N, min, max, periodic ); Mesh* pMesh = new Mesh( "pMesh", nx, "legendre", N-2, min, max, periodic ); bool vert[2] = { false, true }; bool horiz[2] = { false, false }; BCs* vbcs = new BCs( vert, vert, horiz, horiz, vMesh, 0 ); BCs* hbcs = new BCs( false, false, false, false, pMesh, 2*vMesh->nVertsTotal - vbcs->size[0] - vbcs->size[1] ); Field* vel = new Field( "vel", vMesh, 2, vbcs ); Field* eta = new Field( "eta", pMesh, 1, hbcs ); Field* pvel = new Field( "pvel", vMesh, 2, vbcs ); Field* peta = new Field( "peta", pMesh, 1, hbcs ); Field* tvel = new Field( "tvel", vMesh, 2, vbcs ); Field* teta = new Field( "teta", pMesh, 1, hbcs ); Field* vAnal = new Field( "vAnal", vMesh, 2, NULL ); Field* pAnal = new Field( "pAnal", pMesh, 1, NULL ); double time = 0.0; double dt = 0.25*(max[0] - min[0])/(nx[0]*N); int timeStep; int nTimeSteps = 100; double vxErr[100]; double vyErr[100]; double pErr[100]; int dumpEvery = 1; Field* fields[2]; LinearShallowWaterEqn* sw; ofstream file; PetscInitialize( &argc, &argv, (char*)0, tag ); sw = new LinearShallowWaterEqn( vel, eta, F0, BETA, 1.0, 0.0, 0.0, 0.0, dt, 0, NULL ); sw->uNullSp = true; vMesh->Save(); pMesh->Save(); vxErr[0] = vyErr[0] = pErr[0] = 0.0; /* initialise */ vel->SetICFunc( 0, u0 ); vel->SetICFunc( 1, v0 ); eta->SetICFunc( 0, h0 ); vel->SetBCConst( "bottom", 1, 0.0 ); vel->SetBCConst( "top", 1, 0.0 ); pvel->Copy( vel ); peta->Copy( eta ); SetAnalytic( vAnal, pAnal, time ); WriteXDMFHeader( 0 ); fields[0] = vel; fields[1] = vAnal; WriteXDMF( fields, 2, 0, time, dt ); fields[0] = eta; fields[1] = pAnal; WriteXDMF( fields, 2, 0, time, dt ); WriteXDMFFooter( 0 ); /* 1st time step */ time += dt; cout << "time step: " << 1 << ",\tdt: " << dt << ",\ttime: " << time << endl; sw->Solve( NULL, NULL, 1 ); SetAnalytic( vAnal, pAnal, time ); vxErr[timeStep] = FieldError( vel, vAnal, 0, true ); vyErr[timeStep] = FieldError( vel, vAnal, 1, true ); pErr[timeStep] = FieldError( eta, pAnal, 0, true ); cout << "vx error: " << vxErr[timeStep] << "\tvx error: " << vyErr[timeStep] << "\tp error: " << pErr[timeStep] << endl; WriteXDMFHeader( 1 ); fields[0] = vel; fields[1] = vAnal; WriteXDMF( fields, 2, 1, time, dt ); fields[0] = eta; fields[1] = pAnal; WriteXDMF( fields, 2, 1, time, dt ); WriteXDMFFooter( 1 ); for( timeStep = 2; timeStep <= nTimeSteps; timeStep++ ) { time += dt; cout << "time step: " << timeStep << ",\tdt: " << dt << ",\ttime: " << time << endl; tvel->Copy( vel ); teta->Copy( eta ); sw->Solve( pvel, peta, timeStep ); /* assemble the linear operator the first time this is called only */ if( timeStep%dumpEvery == 0 ) { SetAnalytic( vAnal, pAnal, time ); vxErr[timeStep] = FieldError( vel, vAnal, 0, true ); vyErr[timeStep] = FieldError( vel, vAnal, 1, true ); pErr[timeStep] = FieldError( eta, pAnal, 0, true ); cout << "vx error: " << vxErr[timeStep] << "\tvx error: " << vyErr[timeStep] << "\tp error: " << pErr[timeStep] << endl; WriteXDMFHeader( timeStep ); fields[0] = vel; fields[1] = vAnal; WriteXDMF( fields, 2, timeStep, time, dt ); fields[0] = eta; fields[1] = pAnal; WriteXDMF( fields, 2, timeStep, time, dt ); WriteXDMFFooter( timeStep ); } pvel->Copy( tvel ); peta->Copy( teta ); } file.open( "rk_err.txt" ); for( int i = 0; i < nTimeSteps; i++ ) { file << i << "\t" << i*dt << "\t" << vxErr[i] << "\t" << vyErr[i] << "\t" << pErr[i] << endl; } file.close(); delete sw; delete vAnal; delete pAnal; delete teta; delete tvel; delete peta; delete pvel; delete vel; delete eta; delete hbcs; delete vbcs; delete pMesh; delete vMesh; PetscFinalize(); return 0; }
void TwoLayerSW::SolveSecondOrder( Field* velTopPrev, Field* velBotPrev, Field* etaIntPrev ) { Advector* velTopAdv = new Advector( velTop, velTop, velTopPrev, velTopPrev ); Advector* velBotAdv = new Advector( velBot, velBot, velBotPrev, velBotPrev ); /* interfacial pressure rhs ops */ FieldRHS* eta1RHS; FieldRHS* eta2RHS; DivHeightVelRHS* dEtaVel1CurrRHS; DivHeightVelRHS* dEtaVel2CurrRHS; DivHeightVelRHS* dEtaVel1PrevRHS; DivHeightVelRHS* dEtaVel2PrevRHS; PhiRHS* u1RHS; PhiRHS* u2RHS; /* momentum eqn rhs ops */ FieldRHS* velRHS; GradFieldRHS* gPresRHS; WindStress2RHS* windRHS; GradFieldRHS* gEtaRHS; RHSOp** ops; Vector* sol; Vector* rhs; Vec f; Vec x; KSP ksp; MatNullSpace null; Field* etaIntTemp = new Field( "etaIntTemp", etaInt->mesh, 1, etaInt->bcs ); Field* velTopNew = new Field( "vel-top-new", velTop->mesh, 2, velTop->bcs ); Field* velBotNew = new Field( "vel-bot-new", velBot->mesh, 2, velBot->bcs ); etaIntTemp->Copy( etaInt ); for( int i = 0; i < velTop->mesh->nVertsTotal; i++ ) { velTopNew->vals[i][0] = 2.0*velTop->vals[i][0] - velTopPrev->vals[i][0]; velTopNew->vals[i][1] = 2.0*velTop->vals[i][1] - velTopPrev->vals[i][1]; velBotNew->vals[i][0] = 2.0*velBot->vals[i][0] - velBotPrev->vals[i][0]; velBotNew->vals[i][1] = 2.0*velBot->vals[i][1] - velBotPrev->vals[i][1]; } //SolvePressureSecondOrder( velTopPrev, velBotPrev, etaIntPrev ); CreateVector( etaInt, &f ); CreateVector( etaInt, &x ); velTopAdv->Advect( dt ); velBotAdv->Advect( dt ); sol = new Vector( "e-sol", etaInt, x, NULL, 0 ); eta1RHS = new FieldRHS( "eta-curr-rhs", etaInt->mesh, +2.0, etaInt ); eta2RHS = new FieldRHS( "eta-prev-rhs", etaInt->mesh, -0.5, etaIntPrev ); dEtaVel1CurrRHS = new DivHeightVelRHS( "d-eta-vel-1-curr-rhs", etaInt->mesh, -1.0*dt, etaInt, velTop ); dEtaVel1PrevRHS = new DivHeightVelRHS( "d-eta-vel-1-prev-rhs", etaInt->mesh, +0.5*dt, etaIntPrev, velTopPrev ); dEtaVel2CurrRHS = new DivHeightVelRHS( "d-eta-vel-2-curr-rhs", etaInt->mesh, -1.0*dt, etaInt, velBot ); dEtaVel2PrevRHS = new DivHeightVelRHS( "d-eta-vel-2-prev-rhs", etaInt->mesh, +0.5*dt, etaIntPrev, velBotPrev ); u1RHS = new PhiRHS( "u1-rhs", etaInt->mesh, 1.5, velTopNew, +1.0, dt, params->H1, params->tau, params->k, params->nu, params->p, params->f, params->beta, presSurf, etaInt, velTopAdv->fieldSL ); u2RHS = new PhiRHS( "u2-rhs", etaInt->mesh, 1.5, velBotNew, -1.0, dt, params->H2, 0.0, 0.0, params->nu, params->p, params->f, params->beta, presSurf, etaInt, velBotAdv->fieldSL ); ops = new RHSOp*[8]; ops[0] = eta1RHS; ops[1] = eta2RHS; ops[2] = dEtaVel1CurrRHS; ops[3] = dEtaVel1PrevRHS; ops[4] = dEtaVel2CurrRHS; ops[5] = dEtaVel2PrevRHS; ops[6] = u1RHS; ops[7] = u2RHS; rhs = new Vector( "e-rhs", etaInt, f, ops, 8 ); rhs->Assemble(); KSPCreate( MPI_COMM_WORLD, &ksp ); KSPSetOperators( ksp, PI, PI, SAME_NONZERO_PATTERN ); KSPSetOptionsPrefix( ksp, "eta-int_" ); KSPSetFromOptions( ksp ); if( enull ) { MatNullSpaceCreate( MPI_COMM_WORLD, PETSC_TRUE, 0, PETSC_NULL, &null ); KSPSetNullSpace( ksp, null ); } KSPSolve( ksp, f, x ); sol->UpdateField(); if( enull ) { MatNullSpaceDestroy( null ); } KSPDestroy( ksp ); delete sol; delete rhs; VecDestroy( f ); VecDestroy( x ); /* update the upper layer velocity field */ CreateVector( velTop, &x ); CreateVector( velTop, &f ); velRHS = new FieldRHS( "vel-1-rhs", velTop->mesh, 1.0, velTopAdv->fieldSL ); gPresRHS = new GradFieldRHS( "g-pres-rhs", velTop->mesh, -dt*params->p, presSurf ); windRHS = new WindStress2RHS( "wind-rhs", velTop->mesh, dt*params->tau, etaIntTemp, params->k, params->H1 ); ops = new RHSOp*[3]; ops[0] = velRHS; ops[1] = gPresRHS; ops[2] = windRHS; rhs = new Vector( "u1-rhs", velTop, f, ops, 3 ); sol = new Vector( "u1-sol", velTop, x, NULL, 0 ); rhs->Assemble(); KSPCreate( MPI_COMM_WORLD, &ksp ); KSPSetOperators( ksp, VI, VI, SAME_NONZERO_PATTERN ); KSPSetOptionsPrefix( ksp, "vel-top_" ); KSPSetFromOptions( ksp ); KSPSolve( ksp, f, x ); sol->UpdateField(); KSPDestroy( ksp ); delete sol; delete rhs; VecDestroy( f ); VecDestroy( x ); /* update the lower layer velocity field */ CreateVector( velBot, &x ); CreateVector( velBot, &f ); velRHS = new FieldRHS( "vel-2-rhs", velBot->mesh, 1.0, velBotAdv->fieldSL ); gPresRHS = new GradFieldRHS( "g-pres-rhs", velBot->mesh, -dt*params->p, presSurf ); gEtaRHS = new GradFieldRHS( "g-eta-rhs", velBot->mesh, -dt*params->g, etaInt ); ops = new RHSOp*[3]; ops[0] = velRHS; ops[1] = gPresRHS; ops[2] = gEtaRHS; rhs = new Vector( "u2-rhs", velBot, f, ops, 3 ); sol = new Vector( "u2-sol", velBot, x, NULL, 0 ); rhs->Assemble(); KSPCreate( MPI_COMM_WORLD, &ksp ); KSPSetOperators( ksp, VI, VI, SAME_NONZERO_PATTERN ); KSPSetOptionsPrefix( ksp, "vel-bot_" ); KSPSetFromOptions( ksp ); KSPSolve( ksp, f, x ); sol->UpdateField(); KSPDestroy( ksp ); delete sol; delete rhs; VecDestroy( f ); VecDestroy( x ); delete velTopAdv; delete velBotAdv; delete etaIntTemp; delete velTopNew; delete velBotNew; }
int main( int argc, char** argv ) { char tag[6] = "petsc"; int nx[2] = { 80, 20 }; bool periodic[2] = { true, false }; double min[2] = { -4.0*M_PI, -M_PI }; double max[2] = { +4.0*M_PI, +M_PI }; Mesh* mesh = new Mesh( "mesh", nx, "legendre", 5, min, max, periodic ); BCs* bcs = new BCs( true, true, false, false, mesh, 0 ); Field* phi = new Field( "phi-curr", mesh, 1, bcs ); Field* omega = new Field( "omega-curr", mesh, 1, NULL ); Field* phiPrev = new Field( "phi-prev", mesh, 1, bcs ); Field* omegaPrev = new Field( "omega-prev", mesh, 1, NULL ); Field* phiAnal = new Field( "phi-anal", mesh, 1, NULL ); Field* omegaAnal = new Field( "omega-anal", mesh, 1, NULL ); Field* velAnal = new Field( "vel-anal", mesh, 2, NULL ); Field* fields[6]; double dt = 0.01; int timeStep = atoi( argv[1] ); double time = timeStep*dt; int dumpEvery = 1; int nTimeSteps = 400; QuasiGeostrophicEqn* qg; PetscInitialize( &argc, &argv, (char)0, tag ); LoadYStruct( mesh->nVerts[1] ); if( timeStep > 0 ) { phi->Read( timeStep ); omega->Read( timeStep ); } else { GenAnalytic( phi, omega, time ); GenVelocity( velAnal, time ); GenShear( phi, omega, velAnal, true ); } fields[0] = phi; fields[1] = phiAnal; fields[2] = omega; fields[3] = omegaAnal; fields[5] = velAnal; mesh->Save(); //qg = new QuasiGeostrophicEqn( omega, phi, F1, BETA, dt ); qg = new QuasiGeostrophicEqn( phi, omega, F1, BETA, 0.0, 0.0, dt ); if( timeStep == 0 ) { GenAnalytic( phiAnal, omegaAnal, time ); GenVelocity( velAnal, time ); fields[4] = qg->GenVel( phi ); GenShear( phi, omega, fields[4], false ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 6, timeStep, time, dt ); WriteXDMFFooter( timeStep ); GenShear( phi, omega, fields[4], true ); delete fields[4]; } phiPrev->Copy( phi ); omegaPrev->Copy( omega ); time += dt; timeStep++; GenAnalytic( phi, omega, time ); GenVelocity( velAnal, time ); GenShear( phi, omega, velAnal, true ); GenAnalytic( phiAnal, omegaAnal, time ); fields[4] = qg->GenVel( phi ); GenShear( phi, omega, fields[4], false ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 6, timeStep, time, dt ); WriteXDMFFooter( timeStep ); GenShear( phi, omega, fields[4], true ); delete fields[4]; for( timeStep++; timeStep <= nTimeSteps; timeStep++ ) { time += dt; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; //qg->Solve( phiPrev, omegaPrev ); qg->Solve( NULL, NULL ); if( timeStep%dumpEvery == 0 ) { fields[4] = qg->GenVel( phi ); GenVelocity( velAnal, time ); GenAnalytic( phiAnal, omegaAnal, time ); GenShear( phi, omega, fields[4], false ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 6, timeStep, time, dt ); WriteXDMFFooter( timeStep ); WriteXDMFTemporal( timeStep, dumpEvery ); GenShear( phi, omega, fields[4], true ); delete fields[4]; } } delete qg; delete mesh; delete bcs; delete phi; delete omega; delete phiPrev; delete omegaPrev; delete phiAnal; delete omegaAnal; delete velAnal; delete[] A; delete[] dA; delete[] d2A; PetscFinalize(); return EXIT_SUCCESS; }
int main( int argc, char** argv ) { int nx[2] = { 128, 128 }; bool periodic[2] = { true, true }; double min[2] = { 0.0, 0.0 }; double max[2] = { 1.0, 1.0 }; Mesh* mesh = new Mesh( "mesh", nx, "quadratic", 2, min, max, periodic ); Field* velocity = new Field( "velocity", mesh, 2, NULL ); Field* streamFunc = new Field( "streamFunc", mesh, 1, NULL ); Field* vorticity = new Field( "vorticity", mesh, 1, NULL ); Field* prevVort = new Field( "prevVort", mesh, 1, NULL ); Field* tempVort = new Field( "tempVort", mesh, 1, NULL ); Field* prevVel = new Field( "prevVel", mesh, 2, NULL ); Field* tempVel = new Field( "tempVel", mesh, 2, NULL ); Field* fields[3]; int timeStep = 0; int dumpEvery = 2; double time = 0.0; double dt = 0.5*1.0/128.0; QuasiGeostrophicSpectral* qg = new QuasiGeostrophicSpectral( vorticity, streamFunc, velocity, 200.0 ); fields[0] = vorticity; fields[1] = streamFunc; fields[2] = velocity; InitFields( vorticity, velocity, qg ); mesh->Save(); WriteXDMFHeader( 0 ); WriteXDMF( fields, 1, 0, 0.0, dt ); WriteXDMFFooter( 0 ); /* first time step */ time += dt; timeStep++; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; qg->Solve( dt, NULL, NULL ); prevVort->Copy( vorticity ); prevVel->Copy( velocity ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); /* second time step */ time += dt; timeStep++; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; qg->Solve( dt, NULL, NULL ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); for( timeStep = 3; timeStep <= 1000; timeStep++ ) { time += dt; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; tempVort->Copy( vorticity ); tempVel->Copy( velocity ); qg->Solve( dt, prevVort, prevVel ); prevVort->Copy( tempVort ); prevVel->Copy( tempVel ); if( timeStep%dumpEvery == 0 ) { WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); WriteXDMFTemporal( timeStep, dumpEvery ); } } delete qg; delete velocity; delete streamFunc; delete vorticity; delete prevVort; delete tempVort; delete prevVel; delete tempVel; delete mesh; return 0; }
int main( int argc, char** argv ) { char tag[6] = "petsc"; int nx[2] = { 48, 12 }; bool periodic[2] = { true, false }; double min[2] = { -4*M_PI, -M_PI }; double max[2] = { +4*M_PI, +M_PI }; Mesh* mesh = new Mesh( "mesh", nx, "legendre", 8, min, max, periodic ); BCs* bcs = new BCs( true, true, false, false, mesh, 0 ); BCs* none = new BCs( false, false, false, false, mesh, 0 ); Field* phi = new Field( "phi", mesh, 1, bcs ); Field* omega = new Field( "omega", mesh, 1, none ); Field* phiPrev = new Field( "phi-prev", mesh, 1, bcs ); Field* omegaPrev = new Field( "omega-prev", mesh, 1, NULL ); Field* fields[3]; double dt = 0.5*(8*M_PI/nx[0])/U0; int timeStep = atoi( argv[1] ); double time = timeStep*dt; int dumpEvery = 10; int nTimeSteps = 8000; QuasiGeostrophicEqn* qg; PetscInitialize( &argc, &argv, (char)0, tag ); mesh->Save(); if( timeStep > 0 ) { phi->Read( timeStep ); omega->Read( timeStep ); } else { phi->SetICFunc( 0, stream_func_ic ); omega->SetICFunc( 0, vorticity_ic ); //CalcStreamFunc( phi, omega ); } qg = new QuasiGeostrophicEqn( phi, omega, F, BETA, 0.0004, 0.0, dt, NULL ); fields[0] = phi; fields[1] = omega; fields[2] = qg->GenVel( phi ); if( timeStep == 0 ) { WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); } /* first time step */ time += dt; timeStep++; phiPrev->Copy( phi ); omegaPrev->Copy( omega ); qg->Solve( NULL, NULL ); delete fields[2]; fields[2] = qg->GenVel( phi ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); for( timeStep++; timeStep <= nTimeSteps; timeStep++ ) { time += dt; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; qg->Solve( phiPrev, omegaPrev ); if( timeStep%dumpEvery == 0 ) { delete fields[2]; fields[2] = qg->GenVel( phi ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); WriteXDMFTemporal( timeStep, dumpEvery ); } } delete qg; delete mesh; delete bcs; delete phi; delete omega; delete phiPrev; delete omegaPrev; delete fields[2]; PetscFinalize(); return EXIT_SUCCESS; }
int main( int argc, char** argv ) { int nx[2] = { 256, 256 }; bool periodic[2] = { true, true }; double min[2] = { 0.0, 0.0 }; double max[2] = { 1.0, 1.0 }; Mesh* mesh = new Mesh( "mesh", nx, "quadratic", 2, min, max, periodic ); Field* velocity = new Field( "velocity", mesh, 2, NULL ); Field* pressure = new Field( "pressure", mesh, 1, NULL ); Field* vorticity = new Field( "vorticity", mesh, 1, NULL ); Field* velPrev = new Field( "velPrev", mesh, 2, NULL ); Field* tempVel = new Field( "tempVel", mesh, 2, NULL ); Field* fields[3]; int timeStep = 0; int dumpEvery = 10; double time = 0.0; double dt = 0.5*1.0/256.0; NavierStokesSpectral* ns = new NavierStokesSpectral( velocity, pressure, 0.0 ); fields[0] = velocity; fields[1] = pressure; fields[2] = vorticity; InitVelocity( velocity, ns ); velPrev->Copy( velocity ); CalcVorticity( vorticity, velocity ); WriteXDMFHeader( 0 ); WriteXDMF( fields, 3, 0, 0.0, dt ); WriteXDMFFooter( 0 ); time += dt; timeStep++; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; ns->Solve( dt, NULL ); if( timeStep%dumpEvery == 0 ) { CalcVorticity( vorticity, velocity ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); } for( timeStep = 2; timeStep <= 10000; timeStep++ ) { time += dt; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; tempVel->Copy( velocity ); ns->Solve( dt, velPrev ); velPrev->Copy( tempVel ); if( timeStep%dumpEvery == 0 ) { CalcVorticity( vorticity, velocity ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 3, timeStep, time, dt ); WriteXDMFFooter( timeStep ); WriteXDMFTemporal( timeStep, dumpEvery ); } } delete ns; delete velocity; delete pressure; delete vorticity; delete velPrev; delete tempVel; delete mesh; return 0; }
int main( int argc, char** argv ) { char tag[6] = "petsc"; int nx[2] = { 192, 12 }; bool periodic[2] = { true, false }; double min[2] = { -LEN*M_PI, -M_PI }; double max[2] = { +LEN*M_PI, +M_PI }; Mesh* mesh = new Mesh( "mesh", nx, "legendre", 5, min, max, periodic ); BCs* bcs = new BCs( true, true, false, false, mesh, 0 ); Field* phi = new Field( "phi", mesh, 1, bcs ); Field* omega = new Field( "omega", mesh, 1, NULL ); Field* phiPrev = new Field( "phi-prev", mesh, 1, bcs ); Field* omegaPrev = new Field( "omega-prev", mesh, 1, NULL ); Field* phia = new Field( "phi-anal", mesh, 1, NULL ); Field* omegaa = new Field( "omega-anal", mesh, 1, NULL ); Field* vela = new Field( "vel-a", mesh, 2, NULL ); Field* phims = new Field( "phi-ms", mesh, 1, NULL ); Field* omegams = new Field( "omega-ms", mesh, 1, NULL ); Field* veln; Field* fields[8]; double dt = 0.01; int timeStep = atoi( argv[1] ); double time = timeStep*dt; int dumpEvery = 1; int nTimeSteps = 400; QuasiGeostrophicEqn* qg; double y; PetscInitialize( &argc, &argv, (char)0, tag ); LoadYStruct( phi ); WriteAbcissa( mesh ); cout << "A0: " << A0 << endl; cout << "Len: " << LEN << endl; cout << "c_p: " << CP << endl; cout << "c_g: " << CG << endl; cout << "C0: " << C0 << endl; cout << "B0: " << B0 << endl; if( timeStep > 0 ) { phi->Read( timeStep ); } else { GenAnalytic( phi, omega, time, true ); } fields[0] = phi; fields[1] = phia; fields[2] = omega; fields[3] = omegaa; //phi->SetBCConst( "bottom", 0, 0.0 ); //phi->SetBCConst( "top" , 0, 0.0 ); mesh->Save(); if( timeStep == 0 ) { GenAnalytic( phia, omegaa, 0.0, false ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 4, timeStep, time, dt ); WriteXDMFFooter( timeStep ); } phiPrev->Copy( phi ); omegaPrev->Copy( omega ); qg = new QuasiGeostrophicEqn( omega, phi, F, BETA, dt ); //qg->shearFac = 1.0/M_PI; qg->shearFac = 0.0; time += dt; timeStep++; GenAnalytic( phi, omega, time, true ); phia->Copy( phi ); omegaa->Copy( omega ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 4, timeStep, time, dt ); WriteXDMFFooter( timeStep ); for( timeStep++; timeStep <= nTimeSteps; timeStep++ ) { time += dt; cout << "solving for time step: " << timeStep << "\tdt: " << dt << "\ttime: " << time << endl; qg->Solve( omegaPrev, phiPrev ); if( timeStep%dumpEvery == 0 ) { GenVelocity( vela, time, false ); veln = qg->GenVel( phi ); for( int i = 0; i < mesh->nVertsTotal; i++ ) { y = mesh->verts[i][1]; veln->vals[i][0] -= y/M_PI; phims->vals[i][0] = phi->vals[i][0] + 0.5*y*y/M_PI; omegams->vals[i][0] = omega->vals[i][0] + 1.0/M_PI; } fields[4] = vela; fields[5] = veln; fields[6] = phims; fields[7] = omegams; GenAnalytic( phia, omegaa, time, false ); WriteXDMFHeader( timeStep ); WriteXDMF( fields, 8, timeStep, time, dt ); WriteXDMFFooter( timeStep ); WriteXDMFTemporal( timeStep, dumpEvery ); } } delete qg; delete mesh; delete bcs; delete phi; delete omega; delete phiPrev; delete omegaPrev; delete phia; delete omegaa; delete phims; delete omegams; delete[] Ay; delete[] dAy; delete[] d2Ay; PetscFinalize(); return EXIT_SUCCESS; }