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); } } } } } }
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"; }
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; }
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, ×tep, &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); } } } } } }