void CODESolver::StartUp(ODESolverBase *ODEBase) { pODEBase=ODEBase; /*double dTMem=rIC.GetTimeInc(); rIC.SetTimeInc(0.0); //pODEBase->EvalAllDiscrete(); rIC.SetTimeInc(dTMem);*/ LoadIC(IC_StepStart | IC_StepPreStart, "===="); // Must Converge States Before Starting CODEDataBlock ODB(this); ODB.Set(eStateConverge, -1, CODEDataBlock::Converge, pODEBase); pODEBase=NULL; }
int main(int argc, char* argv[]) { DataStructure Mesh(argv[6]); int Npts = Mesh.GetNverts(); sparse Diff = AssembleIsotropicDiffusion(Mesh); if(!strcmp(argv[1],"help")) { cout << "==================================================================" << endl; cout << "==================================================================" << endl; cout << "CVFEM PDE solver for Lisegang systems, written by Andrew Abi Mansour" << endl; cout << "------------------------------------------------------------------" << endl; cout << "Program in Computational Science, American University of Beirut" << endl; cout << "==================================================================" << endl; cout << "==================================================================" << endl; cout << "Usage: ./PDES [Order Cond Period Type OutputFname] [Mesh]" << endl << endl; cout << "Order = an integer specifying the BDF order." << endl << endl; cout << "Cond = a string which initializes the simulation if 'Initialize' is selected, otherwise the simulation is resumed " << "based on an input file input.dat" << endl << endl; cout << "Period = a floating point number that specifies the time at which the simulation ends." << endl << endl; exit(1); } else if(argc == 7) { int Order = atoi(argv[2]); char* IC_COND = argv[1]; double PERIOD = atof(argv[3]); char* Type = argv[4]; char* Output = argv[5]; //dt0 = atof(argv[7]); cout << "BDF order : " << Order << endl << "Simulation time : " << PERIOD << endl; if(!strcmp(IC_COND,"Initialize")) cout << "Initializing simulation ..." << endl; else cout << "Resuming simulation ..." << endl; vector dt(Order,dt0); matrix m(Order+3,Npts,.0); tensor x(Nc,m); if(strcmp(IC_COND,"Initialize")) LoadIC(x); else { LoadIC(x(0),a0,.0,Mesh,Type); LoadIC(x(1),0.0,b0,Mesh,Type); } while(t <= PERIOD) NewtonSolver(Mesh,Diff,x,dt,Order); for(int i = 0; i < Nc; i++) x(i)[0].Write(Output); } else { cout << "Error in syntax." << endl; cout << "Type ./PDES help for instructions on how to run the program." << endl; exit(1); } return 0; }
void CODESolver::Integrate(ODESolverBase *ODEBase, double Stop_Time, double Max_dTime, flag OneIteration, flag HoldAdvance) { pODEBase=ODEBase; Time_Stop=Stop_Time; if (m_iMethod != ODE_RK4) m_iStepSizeControl=ODE_SSC_Fixed; rIC.m_TimeIncMx=Min(rIC.m_TimeIncMxRqd, Max_dTime); rIC.m_TimeIncMn=rIC.m_TimeIncMnRqd; dEstMaxDT=0.0; fStepTooLarge=False; fStepSizeTooSmall=0; //nBadVarRange=0; rIC.m_TimeIncMx=Max(1.0e-5, rIC.m_TimeIncMx); rIC.m_TimeIncMn=Max(1.0e-6, rIC.m_TimeIncMn); if (m_iStepSizeControl==ODE_SSC_Fixed) rIC.m_TimeIncNext=rIC.m_TimeIncMx; flag ShortStep=0; rIC.m_TimeIncNext=Range(rIC.m_TimeIncMn, Valid(rIC.m_TimeIncNext) ? rIC.m_TimeIncNext : rIC.m_TimeInc, rIC.m_TimeIncMx); while (rIC.m_Time < Time_Stop && !fStepSizeTooSmall) { double dT_Reqd; rIC.m_TimeInc=rIC.m_TimeIncNext; rIC.m_TimeIncInit=rIC.m_TimeInc; dT_Reqd = Min(Max_dTime, Min(rIC.m_TimeInc, (Time_Stop-rIC.m_Time))); ShortStep = (dT_Reqd < rIC.m_TimeInc * 0.99); rIC.m_TimeInc = dT_Reqd; LoadIC(IC_StepStart | IC_StepPreStart, "===="); // Clear the last Iterations Errors m_BadTolList.Len=0; m_BadLim.Len=0; // Must Converge States Before Starting CODEDataBlock ODB(this); ODB.Set(eStateConverge, -1, CODEDataBlock::Converge, pODEBase); pODEBase->ODEStartStep(); LoadIC(IC_StepStart , "===="); pODEBase->ODEDerivs(); SaveStart(); #if dbgODESolve if (dbgDumpDerivs()) DumpIntegrators(hDumpFile, rIC.m_Time, rIC.m_TimeInc, "Strt"); #endif SetLimits(); int IntLoop=0; m_BadTolList.Len=0; m_BadTolCopy.Len=0; for (flag OK=0; (!OK ) ; ) { m_BadLim.Len=0; IntLoop++; if (IntLoop > 1) { LoadIC(IC_StepReStart ,"=..="); pODEBase->ODEStartStep(); pODEBase->ODEDerivs(); } flag IsBad=0; OK=1; dTimeWrk = rIC.m_TimeInc; IntOneStep(); if (fStepTooLarge) { IsBad=True; } else switch (m_iStepSizeControl) { case ODE_SSC_Var_1: SaveIntermediate(); ReStart(); dTimeWrk *= 0.5; LoadIC(0 , " =="); // Derivatives @ Start still the Same IntOneStep(); if (!fStepTooLarge) { LoadIC(0 , " --"); pODEBase->ODEDerivs(); IntOneStep(); dTimeWrk *= 2.0; CalculateErrors(); IsBad = !StepSizeOK_1(); } break; case ODE_SSC_Var_2 : CalculateErrors(); IsBad=!StepSizeOK_2(); break; default: IsBad=0; break; } // FindOut what action to take // If bad then restart if (IsBad) { if (fStepTooLarge) { rIC.m_TimeInc=dEstMaxDT; ReStart(); OK=0; m_nBadIters++; fStepTooLarge=False; } else if (fStepSizeTooSmall) { rIC.m_TimeIncNext=rIC.m_TimeIncMn; m_nGoodIters++; m_nIters4Step++; } else //if (!fStepSizeTooSmall) { rIC.m_TimeInc=rIC.m_TimeIncRestart; ReStart(); OK=0; m_nBadIters++; m_nIters4Step++; } } else { m_nGoodIters++; m_nIters4Step++; } } // Must be called independently // EvalAllDiscrete(); #if dbgODESolve if (dbgDumpDerivs()) DumpIntegrators(hDumpFile, rIC.m_Time, rIC.m_TimeInc, "Done"); #endif if (ShortStep && !fStepSizeTooSmall) { if (rIC.m_TimeIncNext >= rIC.m_TimeInc) // Test Passed Easily but step was artificially short - use prev dT rIC.m_TimeIncNext=rIC.m_TimeIncInit; break; } rIC.m_TimeIncNext=Min(Max_dTime, rIC.m_TimeIncNext); rIC.m_TimeIncNext=Min(Max_dTime, rIC.m_TimeIncNext); if (OneIteration) break; } pODEBase=NULL; };
int CODESolver::IntOneStep() { //m_SettleTime=SettleTime; // pIntegrator I; double Half_dT=dTimeWrk*0.5; double h6=dTimeWrk/6.0; // CIntegrateIter It(CStateSave::IList); LoadIC(0, "_"); CODEDataBlock ODB(this); switch (m_iMethod) { case ODE_Euler : //m_BadLim.Len=0; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::EulerAdvance, pODEBase); rIC.AdvanceTime(dTimeWrk); ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::EulerFixDV, pODEBase); break; case ODE_RK2 : //m_BadLim.Len=0; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK2AdvanceA, pODEBase); rIC.AdvanceTime(dTimeWrk); if (fStepTooLarge) break; ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::RK2FixDVA, pODEBase); LoadIC(0, "+H"); pODEBase->ODEDerivs(); if (fStepTooLarge) break; //m_BadLim.Len=0; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK2AdvanceB, pODEBase); if (fStepTooLarge) break; ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::RK2FixDVB, pODEBase); break; case ODE_RK4 : ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK4AdvanceA, pODEBase); rIC.AdvanceTime(Half_dT); if (fStepTooLarge) break; //m_BadLim.Len=0; ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::RK4FixDVA, pODEBase); LoadIC(0, "+H/2"); pODEBase->ODEDerivs(); if (fStepTooLarge) break; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK4AdvanceB, pODEBase); if (fStepTooLarge) break; //m_BadLim.Len=0; ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::RK4FixDVB, pODEBase); LoadIC(0,"+H/2"); pODEBase->ODEDerivs(); if (fStepTooLarge) break; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK4AdvanceC, pODEBase); rIC.AdvanceTime(Half_dT); if (fStepTooLarge) break; //m_BadLim.Len=0; ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::RK4FixDVC, pODEBase); LoadIC(0, "+H"); pODEBase->ODEDerivs(); if (fStepTooLarge) break; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK4AdvanceD, pODEBase); if (fStepTooLarge) break; //m_BadLim.Len=0; ODB.Set(eStateFixDV, dTimeWrk, CODEDataBlock::RK4FixDVD, pODEBase); //m_BadLim.Len=0; ODB.Set(eStateAdvance, dTimeWrk, CODEDataBlock::RK4AdvanceE, pODEBase); break; } return 0; };