示例#1
0
/*!
Returns maximum norm if p == 0.
*/
template<class Grid_T> double get_diff_lp_norm(
    const std::vector<uint64_t>& cells,
    const Grid_T& grid,
    const double p,
    const double cell_volume,
    const size_t dimension
) {
    double local_norm = 0, global_norm = 0;
    for (const auto& cell: cells) {
        const auto* const cell_data = grid[cell];
        if (cell_data == NULL) {
            std::cerr << __FILE__ << ":" << __LINE__
                      << ": No data for cell " << cell
                      << std::endl;
            abort();
        }

        const auto curl_of = curl_of_function(grid.geometry.get_center(cell));

        if (p == 0) {
            local_norm = std::max(
                             local_norm,
                             std::fabs((*cell_data)[Curl()][dimension] - curl_of[dimension])
                         );
        } else {
            local_norm += std::pow(
                              std::fabs((*cell_data)[Curl()][dimension] - curl_of[dimension]),
                              p
                          );
        }
    }
    local_norm *= cell_volume;

    if (p == 0) {
        MPI_Comm comm = grid.get_communicator();
        MPI_Allreduce(&local_norm, &global_norm, 1, MPI_DOUBLE, MPI_MAX, comm);
        MPI_Comm_free(&comm);
        return global_norm;
    } else {
        MPI_Comm comm = grid.get_communicator();
        MPI_Allreduce(&local_norm, &global_norm, 1, MPI_DOUBLE, MPI_SUM, comm);
        MPI_Comm_free(&comm);
        return std::pow(global_norm, 1.0 / p);
    }
}
示例#2
0
int physics_run(real t)
{
  // Run communications
  comms.run();

  msg_stack.push("F_rho");
  
  F_rho = -V_dot_Grad(v, rho) - rho*Div(v);

  msg_stack.pop(); msg_stack.push("F_p");

  F_p = -V_dot_Grad(v, p) - gamma*p*Div(v);
  
  msg_stack.pop(); msg_stack.push("F_v");
  
  F_v = -V_dot_Grad(v, v) + ((Curl(B)^B) - Grad(p))/rho;

  if(include_viscos) {
    F_v.x += viscos * Laplacian(F_v.x);
    F_v.y += viscos * Laplacian(F_v.y);
    F_v.z += viscos * Laplacian(F_v.z);
  }
  
  msg_stack.pop(); msg_stack.push("F_B");
  
  F_B = Curl(v^B);

  // boundary conditions

  apply_boundary(F_rho, "density");
  apply_boundary(F_p, "pressure");
  F_v.to_covariant();
  apply_boundary(F_v, "v");
  F_B.to_contravariant();
  apply_boundary(F_B, "B");

  msg_stack.pop(); msg_stack.push("DivB");
  
  divB = Div(B); // Just for diagnostic
  bndry_inner_zero(divB);
  bndry_sol_zero(divB);

  return 0;
}
示例#3
0
文件: fvcCurl.C 项目: Brzous/WindFOAM
tmp<GeometricField<Type, fvPatchField, volMesh> >
curl
(
    const tmp<GeometricField<Type, fvPatchField, volMesh> >& tvf
)
{
    tmp<GeometricField<Type, fvPatchField, volMesh> > Curl(fvc::curl(tvf()));
    tvf.clear();
    return Curl;
}
示例#4
0
int main(int argc, char* argv[])
{
    if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
        std::cerr << "Couldn't initialize MPI." << std::endl;
        abort();
    }

    MPI_Comm comm = MPI_COMM_WORLD;

    int rank = 0, comm_size = 0;
    if (MPI_Comm_rank(comm, &rank) != MPI_SUCCESS) {
        std::cerr << "Couldn't obtain MPI rank." << std::endl;
        abort();
    }
    if (MPI_Comm_size(comm, &comm_size) != MPI_SUCCESS) {
        std::cerr << "Couldn't obtain size of MPI communicator." << std::endl;
        abort();
    }


    // intialize Zoltan
    float zoltan_version;
    if (Zoltan_Initialize(argc, argv, &zoltan_version) != ZOLTAN_OK) {
        std::cerr << "Zoltan_Initialize failed." << std::endl;
        abort();
    }

    const unsigned int neighborhood_size = 0;
    const int max_refinement_level = 0;

    double
    old_norm_x = std::numeric_limits<double>::max(),
    old_norm_y = std::numeric_limits<double>::max(),
    old_norm_z = std::numeric_limits<double>::max();
    size_t old_nr_of_cells = 0;
    for (size_t nr_of_cells = 8; nr_of_cells <= 64; nr_of_cells *= 2) {

        dccrg::Dccrg<Cell, dccrg::Cartesian_Geometry> grid;

        const std::array<uint64_t, 3> grid_size{{nr_of_cells + 2, nr_of_cells + 2, nr_of_cells + 2}};

        if (
            not grid.initialize(
                grid_size,
                comm,
                "RANDOM",
                neighborhood_size,
                max_refinement_level,
                false,
                false,
                false
            )
        ) {
            std::cerr << __FILE__ << ":" << __LINE__
                      << ": Couldn't initialize grid."
                      << std::endl;
            abort();
        }

        const std::array<double, 3>
        cell_length{{
                double(3) / (grid_size[0] - 2),
                1.5 / (grid_size[1] - 2),
                double(4) / (grid_size[2] - 2)
            }},
        grid_start{{
                -1 - cell_length[0],
                -M_PI / 4 - cell_length[1],
                -2 - cell_length[2]
            }};

        const double cell_volume
            = cell_length[0] * cell_length[1] * cell_length[2];

        dccrg::Cartesian_Geometry::Parameters geom_params;
        geom_params.start = grid_start;
        geom_params.level_0_cell_length = cell_length;

        if (not grid.set_geometry(geom_params)) {
            std::cerr << __FILE__ << ":" << __LINE__
                      << ": Couldn't set grid geometry."
                      << std::endl;
            abort();
        }

        grid.balance_load();

        const auto all_cells = grid.get_cells();
        for (const auto& cell: all_cells) {
            auto* const cell_data = grid[cell];
            if (cell_data == NULL) {
                std::cerr << __FILE__ << ":" << __LINE__
                          << ": No data for cell " << cell
                          << std::endl;
                abort();
            }

            (*cell_data)[Vector()] = function(grid.geometry.get_center(cell));
        }
        grid.update_copies_of_remote_neighbors();

        std::vector<uint64_t> solve_cells;
        for (const auto& cell: all_cells) {
            const auto index = grid.mapping.get_indices(cell);
            if (
                index[0] > 0
                and index[0] < grid_size[0] - 1
                and index[1] > 0
                and index[1] < grid_size[1] - 1
                and index[2] > 0
                and index[2] < grid_size[2] - 1
            ) {
                solve_cells.push_back(cell);
            }
        }

        pamhd::divergence::get_curl(
            solve_cells,
            grid,
        [](Cell& cell_data) -> Vector::data_type& {
            return cell_data[Vector()];
        },
        [](Cell& cell_data) -> Curl::data_type& {
            return cell_data[Curl()];
        }
        );

        const double
        p_of_norm = 2,
        norm_x = get_diff_lp_norm(solve_cells, grid, p_of_norm, cell_volume, 0),
        norm_y = get_diff_lp_norm(solve_cells, grid, p_of_norm, cell_volume, 1),
        norm_z = get_diff_lp_norm(solve_cells, grid, p_of_norm, cell_volume, 2);

        if (norm_x > old_norm_x) {
            if (grid.get_rank() == 0) {
                std::cerr << __FILE__ << ":" << __LINE__
                          << ": X norm with " << nr_of_cells
                          << " cells " << norm_x
                          << " is larger than with " << nr_of_cells / 2
                          << " cells " << old_norm_x
                          << std::endl;
            }
            abort();
        }
        if (norm_y > old_norm_y) {
            if (grid.get_rank() == 0) {
                std::cerr << __FILE__ << ":" << __LINE__
                          << ": Y norm with " << nr_of_cells
                          << " cells " << norm_y
                          << " is larger than with " << nr_of_cells / 2
                          << " cells " << old_norm_y
                          << std::endl;
            }
            abort();
        }
        if (norm_z > old_norm_z) {
            if (grid.get_rank() == 0) {
                std::cerr << __FILE__ << ":" << __LINE__
                          << ": Z norm with " << nr_of_cells
                          << " cells " << norm_z
                          << " is larger than with " << nr_of_cells / 2
                          << " cells " << old_norm_z
                          << std::endl;
            }
            abort();
        }

        if (old_nr_of_cells > 0) {
            const double
            order_of_accuracy_x
                = -log(norm_x / old_norm_x)
                  / log(double(nr_of_cells) / old_nr_of_cells),
                  order_of_accuracy_y
                  = -log(norm_y / old_norm_y)
                    / log(double(nr_of_cells) / old_nr_of_cells),
                    order_of_accuracy_z
                    = -log(norm_z / old_norm_z)
                      / log(double(nr_of_cells) / old_nr_of_cells);

            if (order_of_accuracy_x < 1.95) {
                if (grid.get_rank() == 0) {
                    std::cerr << __FILE__ << ":" << __LINE__
                              << ": Order of accuracy from "
                              << old_nr_of_cells << " to " << nr_of_cells
                              << " is too low for x: " << order_of_accuracy_x
                              << std::endl;
                }
                abort();
            }
            if (order_of_accuracy_y < 1.95) {
                if (grid.get_rank() == 0) {
                    std::cerr << __FILE__ << ":" << __LINE__
                              << ": Order of accuracy from "
                              << old_nr_of_cells << " to " << nr_of_cells
                              << " is too low for y: " << order_of_accuracy_y
                              << std::endl;
                }
                abort();
            }
            if (order_of_accuracy_z < 1.95) {
                if (grid.get_rank() == 0) {
                    std::cerr << __FILE__ << ":" << __LINE__
                              << ": Order of accuracy from "
                              << old_nr_of_cells << " to " << nr_of_cells
                              << " is too low for z: " << order_of_accuracy_z
                              << std::endl;
                }
                abort();
            }
        }

        old_nr_of_cells = nr_of_cells;
        old_norm_x = norm_x;
        old_norm_y = norm_y;
        old_norm_z = norm_z;
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}