void ThermoMechanicalCoefficients<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  Intrepid2::Tensor<ScalarT> diffusivity(num_dims_);
  Intrepid2::Tensor<ScalarT> I(Intrepid2::eye<ScalarT>(num_dims_));
  Intrepid2::Tensor<ScalarT> tensor;
  Intrepid2::Tensor<ScalarT> F(num_dims_);

  ScalarT dt = delta_time_(0);
  if (dt == 0.0) dt = 1.e-15;
  Albany::MDArray temperature_old = (*workset.stateArrayPtr)[temperature_name_];
  for (int cell = 0; cell < workset.numCells; ++cell) {
    for (int pt = 0; pt < num_pts_; ++pt) {
      temperature_dot_(cell,pt) =
        (temperature_(cell,pt) - temperature_old(cell,pt)) / dt;
    }
  }

  if (have_mech_) {
    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int pt = 0; pt < num_pts_; ++pt) {
        F.fill(def_grad_,cell, pt,0,0);
        tensor = Intrepid2::inverse(Intrepid2::transpose(F) * F);
        thermal_transient_coeff_(cell, pt) = transient_coeff_;
        diffusivity = thermal_cond_(cell, pt) / (density_ * heat_capacity_)
            * tensor;
        for (int i = 0; i < num_dims_; ++i) {
          for (int j = 0; j < num_dims_; ++j) {
            thermal_diffusivity_(cell, pt, i, j) = diffusivity(i, j);
          }
        }
      }
    }
  } else {
    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int pt = 0; pt < num_pts_; ++pt) {
        thermal_transient_coeff_(cell, pt) = transient_coeff_;
        diffusivity = thermal_cond_(cell, pt) / (density_ * heat_capacity_) * I;
        for (int i = 0; i < num_dims_; ++i) {
          for (int j = 0; j < num_dims_; ++j) {
            thermal_diffusivity_(cell, pt, i, j) = diffusivity(i, j);
          }
        }
      }
    }
  }
}
Пример #2
0
void HeatPDE_CL::fillInitialConditions(ExactSolution* exact) {
    // Fill U_G with initial conditions
    this->HeatPDE::fillInitialConditions(exact);

    this->sendrecvUpdates(U_G, "U_G");

    unsigned int nb_nodes = grid_ref.G.size();
    unsigned int solution_mem_bytes = nb_nodes*this->getFloatSize();

    std::vector<double> diffusivity(nb_nodes, 0.);

    //FIXME: we're assuming float type on diffusivity. IF we need double, we'll
    //have to move this down.
    this->fillDiffusion(diffusivity, U_G, 0., nb_nodes);

    std::cout << "[HeatPDE_CL] Writing initial conditions to GPU\n";
    if (useDouble) {

        // Fill GPU mem with initial solution
        err = queue.enqueueWriteBuffer(gpu_solution[INDX_IN], CL_FALSE, 0, solution_mem_bytes, &U_G[0], NULL, &event);

        err = queue.enqueueWriteBuffer(gpu_diffusivity, CL_FALSE, 0, solution_mem_bytes, &diffusivity[0], NULL, &event);

        queue.finish();
    } else {

        float* U_G_f = new float[nb_nodes];
        float* diffusivity_f = new float[nb_nodes];
        for (unsigned int i = 0; i < nb_nodes; i++) {
            U_G_f[i] = (float)U_G[i];
            diffusivity_f[i] = (float)diffusivity[i];
        }
        err = queue.enqueueWriteBuffer(gpu_solution[INDX_IN], CL_FALSE, 0, solution_mem_bytes, &U_G_f[0], NULL, &event);

        err = queue.enqueueWriteBuffer(gpu_diffusivity, CL_FALSE, 0, solution_mem_bytes, &diffusivity_f[0], NULL, &event);
        queue.finish();

        delete [] U_G_f;
        delete [] diffusivity_f;

    }

    // FIXME: change all unsigned int to int. Or unsigned int. Size_t is not supported by GPU.
    std::vector<unsigned int>& bindices = grid_ref.getBoundaryIndices();
    unsigned int nb_bnd = bindices.size();
    err = queue.enqueueWriteBuffer(gpu_boundary_indices, CL_FALSE, 0, nb_bnd*sizeof(unsigned int), &bindices[0], NULL, &event);

    std::cout << "[HeatPDE_CL] Done\n";
}
Пример #3
0
const std::vector<T> nonlinearIsotropicDiffusion(const std::vector<T> & signal,
                                                 T (* diffusivity)(T),
                                                 T time,
                                                 T step_size = 0.25,
                                                 BorderInterpolation interpolation_method = CONTINUED)
{
    /* The general formulation of a nonlinear diffusion is
     *
     *      d/dt f(x, t) = div [ D(grad f(x, t)) * grad f(x, t) ]
     *
     * where D is the so-called diffusivity. In the 1-dimensional case, the
     * divergence and the gradient simplify to an ordinary differentiation.
     * Thus we get
     *
     *      d/dt f(x, t) = d/dx [ D(d/dx f(x, t)) * d/dx f(x, t) ]
     *
     * The diffusion equation can be easily solved by using the following
     * approximation
     *
     *      d/dt f(x, t) = [f(x, t+h) - f(x, t) ] / h
     *
     * where h is the step size. With this, we get (A, B, and C are used within
     * the implementation)
     *
     *      d/dt f(x, t+h) = f(x, t) + h *  { d/dx [ D(d/dx f(x, t)) * d/dx f(x, t) ] }
     *                     = f(x, t) + h *  { d/dx [ D(A)            * A            ] }
     *                     = f(x, t) + h *  { d/dx [ B                              ] }
     *                     = f(x, t) + h *  { C                                       }
     *
     * Iterating until t + n * h = time, yields the solution.
     */


    // If time == 0 return the unchanged signal.

    if (Tools::isZero(time))
    {
        return signal;
    }

    // Modify step_size such, that after n iterations, time is really reached.

    step_size = time / std::ceil(time / step_size);

    // Compute the diffusion.

    const unsigned N = signal.size();
    std::vector<T> B(N);

    std::vector<T> diffused_signal = signal;

    for (T t = step_size; t <= time; t += step_size)
    {
        const std::vector<T> & A = firstDerivative(diffused_signal, interpolation_method);

        for (unsigned i = 0; i < N; ++i)
        {
            B[i] = diffusivity(A[i]) * A[i];
        }

        const std::vector<T> & C = firstDerivative(B, interpolation_method);

        for (unsigned i = 0; i < signal.size(); ++i)
        {
            diffused_signal[i] = diffused_signal[i] + step_size * C[i];
        }
    }

    return diffused_signal;
}
Пример #4
0
int main(int argc, char **args) {

  double maxdepth;
  double maxtime;
  double vertlayer;
  double timestep;
  double surfacerate;
  double surfacepressure;
  double c13diffusivityfactor;
  double c13prodfactor;
  double tortuosity;
  double qfactor;
  double dao;
  double d;
  double A0;
  double TAverage;
  Delta13CSimulation sim;

  //Read the config-file
  readConfig(&maxdepth, &maxtime, &vertlayer, &timestep, &surfacerate, &surfacepressure, &c13diffusivityfactor, &tortuosity, &qfactor, &dao, &d, &A0, &TAverage, &c13prodfactor);

  //Initialize the simulation
  printf("Initialize the parameters, allocate memory...\n");
  initialize(&sim, maxdepth, maxtime, vertlayer, timestep, surfacerate, surfacepressure, 1, tortuosity, qfactor, dao, 1, "12C");
  printf("Done!\n");

  //Calculate the temperature matrix
  printf("Calculating the temperature matrix ... \n");
  temperature(&sim, d, A0, TAverage);
  printf("Done!\n");
 
  //Calculate the diffusivity matrix
  printf("Calculating the diffusivities ... \n");
  diffusivity(&sim);
  printf("Done!\n");

  //Calculate the CO2 profile
  printf("Calculating the CO2 profiles ... \n");
  co2Production(&sim, VARIABLEPROD);
  printf("Done!\n");

  //Calculate vertical fluxes, the molar density and the delta 13 C
  for(int timeStep = 0; timeStep < sim.timeIndexMax; timeStep++) {
    for(int depthStep = 0; depthStep < sim.depthIndexMax; depthStep++) {
      verticalFlux(&sim, depthStep, timeStep);
      molarDensity(&sim, depthStep, timeStep, AIRFILLEDPOROSITY);
    }
    delta13cSurfaceFlux(&sim, timeStep);
  }

  //Write the results to the HDD
  //printf("Writing results to the HDD ... \n");
  //writeToFile(&sim);
  //writeToFile(&sim2);
  //printf("Done!\n");

  //Deallocate the memory
  printf("Deallocating arrays ... \n");
  cleaning(&sim, -1);
  printf("Done!\n");
  return 0;
}
void
ThermoMechanicalCoefficients<EvalT, Traits>::evaluateFields(
    typename Traits::EvalData workset)
{
  if (SolutionType_ == "Continuation") {
    Albany::MDArray const temperature_old =
        (*workset.stateArrayPtr)[temperature_name_];

    ScalarT dt = delta_time_(0);

    if (dt == 0.0) {
      // Initially, transfer the derivatives of temperature_ to the
      // derivatives of temperature_dot_
      dt = 1.0;
    }

    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int pt = 0; pt < num_pts_; ++pt) {
        temperature_dot_(cell, pt) =
            (temperature_(cell, pt) - temperature_old(cell, pt)) / dt;
      }
    }
  }

  if (have_mech_) {
    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int pt = 0; pt < num_pts_; ++pt) {
        minitensor::Tensor<ScalarT> F(num_dims_);

        F.fill(def_grad_, cell, pt, 0, 0);

        minitensor::Tensor<ScalarT> tensor =
            minitensor::inverse(minitensor::transpose(F) * F);

        thermal_transient_coeff_(cell, pt) = transient_coeff_;

        minitensor::Tensor<ScalarT> diffusivity =
            thermal_cond_(cell, pt) / (density_ * heat_capacity_) * tensor;

        for (int i = 0; i < num_dims_; ++i) {
          for (int j = 0; j < num_dims_; ++j) {
            thermal_diffusivity_(cell, pt, i, j) = diffusivity(i, j);
          }
        }
      }
    }
  } else {
    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int pt = 0; pt < num_pts_; ++pt) {
        thermal_transient_coeff_(cell, pt) = transient_coeff_;

        minitensor::Tensor<RealType> I(minitensor::eye<RealType>(num_dims_));

        minitensor::Tensor<ScalarT> diffusivity =
            thermal_cond_(cell, pt) / (density_ * heat_capacity_) * I;

        for (int i = 0; i < num_dims_; ++i) {
          for (int j = 0; j < num_dims_; ++j) {
            thermal_diffusivity_(cell, pt, i, j) = diffusivity(i, j);
          }
        }
      }
    }
  }
}