⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monoadaptivetimeslab.cpp

📁 利用C
💻 CPP
字号:
// Copyright (C) 2005-2008 Anders Logg.// Licensed under the GNU LGPL Version 2.1.//// First added:  2005-01-28// Last changed: 2008-06-11#include <string>#include <dolfin/common/constants.h>#include <dolfin/log/dolfin_log.h>#include <dolfin/parameter/parameters.h>#include "ODE.h"#include "Method.h"#include "MonoAdaptiveFixedPointSolver.h"#include "MonoAdaptiveNewtonSolver.h"#include "MonoAdaptiveTimeSlab.h"using namespace dolfin;//-----------------------------------------------------------------------------MonoAdaptiveTimeSlab::MonoAdaptiveTimeSlab(ODE& ode)  : TimeSlab(ode), solver(0), adaptivity(ode, *method), nj(0), dofs(0),     fq(0), rmax(0), u(N), f(N){  // Choose solver  solver = chooseSolver();  // Initialize dofs  dofs = new real[method->nsize()];  // Compute the number of dofs  nj = method->nsize() * N;  // Initialize values of right-hand side  const uint fsize = method->qsize() * N;  fq = new real[fsize];  for (uint j = 0; j < fsize; j++)    fq[j] = 0.0;  // Initialize solution  x.init(nj);  // Evaluate f at initial data for cG(q)  if ( method->type() == Method::cG )  {    ode.f(u0, 0.0, f);    copy(f, 0, fq, 0, N);  }}//-----------------------------------------------------------------------------MonoAdaptiveTimeSlab::~MonoAdaptiveTimeSlab(){  if ( solver ) delete solver;  if ( dofs ) delete [] dofs;  if ( fq ) delete [] fq;}//-----------------------------------------------------------------------------real MonoAdaptiveTimeSlab::build(real a, real b){  //cout << "Mono-adaptive time slab: building between "  //     << a << " and " << b << endl;  // Copy initial values to solution  for (uint n = 0; n < method->nsize(); n++)    for (uint i = 0; i < N; i++)      x[n*N + i] = u0[i];  // Choose time step  const real k = adaptivity.timestep();  if ( k < adaptivity.threshold() * (b - a) )    b = a + k;  // Save start and end time  _a = a;  _b = b;  //cout << "Mono-adaptive time slab: finished building between "  //     << a << " and " << b << ": K = " << b - a << endl;  // Update at t = 0.0  if ( a < DOLFIN_EPS )    ode.update(u0, a, false);  return b;}//-----------------------------------------------------------------------------bool MonoAdaptiveTimeSlab::solve(){  //message("Solving time slab system on [%f, %f].", _a, _b);  return solver->solve();}//-----------------------------------------------------------------------------bool MonoAdaptiveTimeSlab::check(bool first){  // Compute offset for f  const uint foffset = (method->qsize() - 1) * N;  // Compute f at end-time  feval(method->qsize() - 1);  // Compute maximum norm of residual at end-time  const real k = length();  rmax = 0.0;  for (uint i = 0; i < N; i++)  {    // Prepare data for computation of derivative    const real x0 = u0[i];    for (uint n = 0; n < method->nsize(); n++)      dofs[n] = x[n*N + i];    // Compute residual    const real r = fabs(method->residual(x0, dofs, fq[foffset + i], k));        // Compute maximum    if ( r > rmax )      rmax = r;  }  // Compute new time step  adaptivity.update(length(), rmax, *method, _b, first);  // Check if current solution can be accepted  return adaptivity.accept();}//-----------------------------------------------------------------------------bool MonoAdaptiveTimeSlab::shift(bool end){  // Compute offsets  const uint xoffset = (method->nsize() - 1) * N;  const uint foffset = (method->qsize() - 1) * N;  // Write solution at final time if we should  if ( save_final && end )  {    copy(x, xoffset, u, 0, N);    write(u);  }  // Let user update ODE  copy(x, xoffset, u, 0, N);  if ( !ode.update(u, _b, end) )    return false;  // Set initial value to end-time value  for (uint i = 0; i < N; i++)    u0[i] = x[xoffset + i];  // Set f at first quadrature point to f at end-time for cG(q)  if ( method->type() == Method::cG )  {    for (uint i = 0; i < N; i++)      fq[i] = fq[foffset + i];  }  return true;}//-----------------------------------------------------------------------------void MonoAdaptiveTimeSlab::sample(real t){  // Compute f at end-time  feval(method->qsize() - 1);}//-----------------------------------------------------------------------------real MonoAdaptiveTimeSlab::usample(uint i, real t){  // Prepare data  const real x0 = u0[i];  const real tau = (t - _a) / (_b - _a);    // Prepare array of values  for (uint n = 0; n < method->nsize(); n++)    dofs[n] = x[n*N + i];  // Interpolate value  const real value = method->ueval(x0, dofs, tau);    return value;}//-----------------------------------------------------------------------------real MonoAdaptiveTimeSlab::ksample(uint i, real t){  return length();}//-----------------------------------------------------------------------------real MonoAdaptiveTimeSlab::rsample(uint i, real t){  // Right-hand side at end-point already computed  // Prepare data for computation of derivative  const real x0 = u0[i];  for (uint n = 0; n < method->nsize(); n++)    dofs[n] = x[n*N + i];    // Compute residual  const real k = length();  const uint foffset = (method->qsize() - 1) * N;  const real r = method->residual(x0, dofs, fq[foffset + i], k);  return r;}//-----------------------------------------------------------------------------void MonoAdaptiveTimeSlab::disp() const{  cout << "--- Mono-adaptive time slab ------------------------------" << endl;  cout << "nj = " << nj << endl;  cout << "x =";  for (uint j = 0; j < nj; j++)    cout << " " << x[j];  cout << endl;  cout << "f =";  for (uint j = 0; j < (method->nsize() * N); j++)    cout << " " << fq[j];  cout << endl;  cout << "----------------------------------------------------------" << endl;}//-----------------------------------------------------------------------------void MonoAdaptiveTimeSlab::feval(uint m){  // Evaluation depends on the choice of method  if ( method->type() == Method::cG )  {    // Special case: m = 0    if ( m == 0 )    {      // We don't need to evaluate f at t = a since we evaluated      // f at t = b for the previous time slab      return;    }    const real t = _a + method->qpoint(m) * (_b - _a);        copy(x, (m - 1)*N, u, 0, N);    ode.f(u, t, f);    copy(f, 0, fq, m*N, N);  }  else  {    const real t = _a + method->qpoint(m) * (_b - _a);        copy(x, m*N, u, 0, N);    ode.f(u, t, f);    copy(f, 0, fq, m*N, N);  }}//-----------------------------------------------------------------------------TimeSlabSolver* MonoAdaptiveTimeSlab::chooseSolver(){  bool implicit = ode.get("ODE implicit");  std::string solver = ode.get("ODE nonlinear solver");  if ( solver == "fixed-point" )  {    if ( implicit )      error("Newton solver must be used for implicit ODE.");    message("Using mono-adaptive fixed-point solver.");    return new MonoAdaptiveFixedPointSolver(*this);  }  else if ( solver == "newton" )  {    if ( implicit )    {      message("Using mono-adaptive Newton solver for implicit ODE.");      return new MonoAdaptiveNewtonSolver(*this, implicit);    }    else    {      message("Using mono-adaptive Newton solver.");      return new MonoAdaptiveNewtonSolver(*this, implicit);    }  }  else if ( solver == "default" )  {    if ( implicit )    {            message("Using mono-adaptive Newton solver (default for implicit ODEs).");      return new MonoAdaptiveNewtonSolver(*this, implicit);    }    else    {      message("Using mono-adaptive fixed-point solver (default for c/dG(q)).");      return new MonoAdaptiveFixedPointSolver(*this);    }  }  else  {    error("Uknown solver type: %s.", solver.c_str());  }  return 0;}//-----------------------------------------------------------------------------real* MonoAdaptiveTimeSlab::tmp(){  // This function provides access to an array that can be used for  // temporary data storage by the Newton solver. We can reuse the  // parts of f that are recomputed in each iteration. Note that this  // needs to be done differently for cG and dG, since cG does not  // recompute the right-hand side at the first quadrature point.  if ( method->type() == Method::cG )    return fq + N;  else    return fq;}//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -