Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Level set: composition (II) #26

Merged
merged 17 commits into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions include/adaflo/level_set_okz_advance_concentration.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,13 @@ class LevelSetOKZSolverAdvanceConcentration
const VectorType & vel_solution,
const VectorType & vel_solution_old,
const VectorType & vel_solution_old_old,
const double & global_omega_diameter,
const AlignedVector<VectorizedArray<double>> &cell_diameters,
const AffineConstraints<double> & constraints,
const ConditionalOStream & pcout,
const LevelSetOKZSolverAdvanceConcentrationBoundaryDescriptor<dim> &boundary,
const MatrixFree<dim> & matrix_free,
const LevelSetOKZSolverAdvanceConcentrationParameter & parameters,
double & global_max_velocity,
const DiagonalPreconditioner<double> &preconditioner);
const DiagonalPreconditioner<double> & preconditioner);

virtual void
advance_concentration(const double dt);
Expand Down Expand Up @@ -167,11 +165,11 @@ class LevelSetOKZSolverAdvanceConcentration
/**
* Physics section
*/
const double & global_omega_diameter; // [i]
double global_omega_diameter; // [i]
const AlignedVector<VectorizedArray<double>> &cell_diameters; // [i]
const LevelSetOKZSolverAdvanceConcentrationBoundaryDescriptor<dim> boundary; // [i]
AlignedVector<VectorizedArray<double>> artificial_viscosities; // [-]
double & global_max_velocity; // [o]
double global_max_velocity; // [o]
AlignedVector<Tensor<1, dim, VectorizedArray<double>>> evaluated_convection; // [o]

/**
Expand Down
7 changes: 0 additions & 7 deletions include/adaflo/level_set_okz_compute_curvature.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include <adaflo/block_matrix_extension.h>
#include <adaflo/diagonal_preconditioner.h>
#include <adaflo/level_set_okz_compute_normal.h>
#include <adaflo/navier_stokes.h>
#include <adaflo/time_stepping.h>
#include <adaflo/util.h>
Expand Down Expand Up @@ -76,7 +75,6 @@ class LevelSetOKZSolverComputeCurvature
{
public:
LevelSetOKZSolverComputeCurvature(
LevelSetOKZSolverComputeNormal<dim> & normal_operator,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The curvature operator does not need the normal operator anymore.

const AlignedVector<VectorizedArray<double>> & cell_diameters,
const LinearAlgebra::distributed::BlockVector<double> &normal_vector_field,
const AffineConstraints<double> & constraints_curvature,
Expand Down Expand Up @@ -120,11 +118,6 @@ class LevelSetOKZSolverComputeCurvature
*/
const LevelSetOKZSolverComputeCurvatureParameter parameters; // [i]

/**
* Other operators.
*/
LevelSetOKZSolverComputeNormal<dim> &normal_operator; // [i]

/**
* Vector section
*/
Expand Down
9 changes: 6 additions & 3 deletions include/adaflo/level_set_okz_compute_normal.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ struct LevelSetOKZSolverComputeNormalParameter
/**
* TODO
*/

bool approximate_projections;
/**
* TODO
*/
double damping_scale_factor = 4.0;
};

template <int dim>
Expand All @@ -70,7 +73,7 @@ class LevelSetOKZSolverComputeNormal
LevelSetOKZSolverComputeNormal(
BlockVectorType & normal_vector_field,
BlockVectorType & normal_vector_rhs,
VectorType & solution,
const VectorType & level_set_field,
const AlignedVector<VectorizedArray<double>> & cell_diameters,
const double & epsilon_used,
const double & minimal_edge_length,
Expand Down Expand Up @@ -112,7 +115,7 @@ class LevelSetOKZSolverComputeNormal
*/
BlockVectorType & normal_vector_field; // [o]
BlockVectorType & normal_vector_rhs; // [-]
const VectorType &vel_solution; // [i]
const VectorType &level_set_solution; // [i]

/**
* MatrixFree
Expand Down
17 changes: 5 additions & 12 deletions include/adaflo/level_set_okz_reinitialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class LevelSetOKZSolverReinitialization
using BlockVectorType = LinearAlgebra::distributed::BlockVector<double>;

LevelSetOKZSolverReinitialization(
LevelSetOKZSolverComputeNormal<dim> & normal_operator,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to pass the normal operator to the constructor.

const BlockVectorType & normal_vector_field,
const AlignedVector<VectorizedArray<double>> & cell_diameters,
const double & epsilon_used,
Expand All @@ -84,7 +83,6 @@ class LevelSetOKZSolverReinitialization
bool & first_reinit_step,
const MatrixFree<dim, double> & matrix_free)
: parameters(parameters)
, normal_operator(normal_operator)
, solution(solution)
, solution_update(solution_update)
, system_rhs(system_rhs)
Expand All @@ -102,11 +100,11 @@ class LevelSetOKZSolverReinitialization
{}

// performs reinitialization
virtual void
reinitialize(const double dt,
const unsigned int stab_steps,
const unsigned int diff_steps = 0,
const bool diffuse_cells_with_large_curvature_only = false);
void
reinitialize(const double dt,
const unsigned int stab_steps,
const unsigned int diff_steps = 0,
const std::function<void(bool)> &compute_normal = [](const bool) {});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead a lambda with the effect.


void
reinitialization_vmult(VectorType & dst,
Expand All @@ -133,11 +131,6 @@ class LevelSetOKZSolverReinitialization
*/
const LevelSetOKZSolverReinitializationParameter parameters;

/**
* Other operators.
*/
LevelSetOKZSolverComputeNormal<dim> &normal_operator;

/**
* Vector section
*/
Expand Down
76 changes: 76 additions & 0 deletions include/adaflo/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <deal.II/distributed/tria.h>

#include <deal.II/matrix_free/matrix_free.h>

using namespace dealii;

/**
Expand Down Expand Up @@ -52,4 +54,78 @@ locally_owned_subdomain(const MeshType &mesh)
return tria_parallel != nullptr ? tria_parallel->locally_owned_subdomain() : 0;
}

template <int dim>
void
compute_cell_diameters(const MatrixFree<dim, double> & matrix_free,
const unsigned int dof_index,
AlignedVector<VectorizedArray<double>> &cell_diameters,
double & cell_diameter_min,
double & cell_diameter_max)
Comment on lines +57 to +63
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mschreter FYI :)

{
cell_diameters.resize(matrix_free.n_cell_batches());

cell_diameter_min = std::numeric_limits<double>::max();
cell_diameter_max = 0.0;

// to find the cell diameters, we compute the maximum and minimum eigenvalue
// of the Jacobian transformation from the unit to the real cell. We check
// all face centers and the center of the cell and take the respective
// minimum and maximum there to cover most of the cell geometry
std::vector<Point<dim>> face_centers;
{
Point<dim> center;
for (unsigned int d = 0; d < dim; ++d)
center[d] = 0.5;
for (unsigned int d = 0; d < dim; ++d)
{
Point<dim> p1 = center;
p1[d] = 0;
face_centers.push_back(p1);
p1[d] = 1.;
face_centers.push_back(p1);
}
face_centers.push_back(center);
}

const auto &dof_handler = matrix_free.get_dof_handler(dof_index);
const auto &triangulation = dof_handler.get_triangulation();

LAPACKFullMatrix<double> mat(dim, dim);
FEValues<dim> fe_values(*matrix_free.get_mapping_info().mapping,
dof_handler.get_fe(),
Quadrature<dim>(face_centers),
update_jacobians);
for (unsigned int cell = 0; cell < matrix_free.n_cell_batches(); ++cell)
{
VectorizedArray<double> diameter = VectorizedArray<double>();
for (unsigned int v = 0; v < matrix_free.n_active_entries_per_cell_batch(cell); ++v)
{
typename DoFHandler<dim>::active_cell_iterator dcell =
matrix_free.get_cell_iterator(cell, v, dof_index);
fe_values.reinit(dcell);
for (unsigned int q = 0; q < fe_values.n_quadrature_points; ++q)
{
mat = 0;
for (unsigned int d = 0; d < dim; ++d)
for (unsigned int e = 0; e < dim; ++e)
mat(d, e) = fe_values.jacobian(q)[d][e];
mat.compute_eigenvalues();
for (unsigned int d = 0; d < dim; ++d)
{
diameter[v] = std::max(diameter[v], std::abs(mat.eigenvalue(d)));
cell_diameter_min =
std::min(cell_diameter_min, std::abs(mat.eigenvalue(d)));
}
}
if (1U + dcell->level() == triangulation.n_global_levels())
cell_diameter_max = std::max(diameter[v], cell_diameter_max);
}
cell_diameters[cell] = diameter;
}
cell_diameter_min =
-Utilities::MPI::max(-cell_diameter_min, get_communicator(triangulation));
cell_diameter_max =
Utilities::MPI::max(cell_diameter_max, get_communicator(triangulation));
}

#endif
22 changes: 15 additions & 7 deletions source/level_set_okz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ LevelSetOKZSolver<dim>::LevelSetOKZSolver(const FlowParameters &parameters_in,
params.time.time_step_size_min = this->parameters.time_step_size_min;

this->reinit_operator = std::make_unique<LevelSetOKZSolverReinitialization<dim>>(
*this->normal_operator,
this->normal_vector_field,
this->cell_diameters,
this->epsilon_used,
Expand Down Expand Up @@ -133,7 +132,6 @@ LevelSetOKZSolver<dim>::LevelSetOKZSolver(const FlowParameters &parameters_in,
params.curvature_correction = this->parameters.curvature_correction;

this->curvatur_operator = std::make_unique<LevelSetOKZSolverComputeCurvature<dim>>(
*this->normal_operator,
this->cell_diameters,
this->normal_vector_field,
this->constraints_curvature,
Expand Down Expand Up @@ -188,14 +186,12 @@ LevelSetOKZSolver<dim>::LevelSetOKZSolver(const FlowParameters &parameters_in,
this->navier_stokes.solution.block(0),
this->navier_stokes.solution_old.block(0),
this->navier_stokes.solution_old_old.block(0),
this->global_omega_diameter,
this->cell_diameters,
this->constraints,
this->pcout,
bcs,
this->matrix_free,
params,
this->global_max_velocity,
this->preconditioner);
}
}
Expand Down Expand Up @@ -464,8 +460,16 @@ template <int dim>
void
LevelSetOKZSolver<dim>::compute_curvature(const bool diffuse_large_values)
{
TimerOutput::Scope timer(*this->timer, "LS compute curvature.");
curvatur_operator->compute_curvature(diffuse_large_values);
// This function computes the curvature from the normal field. Could also
// compute the curvature directly from C, but that is less accurate. TODO:
// include that variant by a parameter
{
this->compute_normal(false);
}
{
TimerOutput::Scope timer(*this->timer, "LS compute curvature.");
curvatur_operator->compute_curvature(diffuse_large_values);
}
}


Expand Down Expand Up @@ -543,11 +547,15 @@ LevelSetOKZSolver<dim>::reinitialize(const unsigned int stab_steps,
const unsigned int diff_steps,
const bool diffuse_cells_with_large_curvature_only)
{
(void)diffuse_cells_with_large_curvature_only;

TimerOutput::Scope timer(*this->timer, "LS reinitialization step.");
reinit_operator->reinitialize(this->time_stepping.step_size(),
stab_steps,
diff_steps,
diffuse_cells_with_large_curvature_only);
[&](const bool fast_computation) {
this->compute_normal(fast_computation);
});
}


Expand Down
39 changes: 35 additions & 4 deletions source/level_set_okz_advance_concentration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ namespace

return Utilities::MPI::max(max_velocity, get_communicator(dof_handler));
}

template <int dim, int spacedim>
double
diameter_on_coarse_grid(const Triangulation<dim, spacedim> &tria)
{
const std::vector<Point<spacedim>> &vertices = tria.get_vertices();
std::vector<bool> boundary_vertices(vertices.size(), false);

for (const auto &cell : tria.cell_iterators_on_level(0))
for (const unsigned int face : cell->face_indices())
if (cell->face(face)->at_boundary())
for (unsigned int i = 0; i < cell->face(face)->n_vertices(); ++i)
boundary_vertices[cell->face(face)->vertex_index(i)] = true;

// now traverse the list of boundary vertices and check distances.
// since distances are symmetric, we only have to check one half
double max_distance_sqr = 0;
std::vector<bool>::const_iterator pi = boundary_vertices.begin();
const unsigned int N = boundary_vertices.size();
for (unsigned int i = 0; i < N; ++i, ++pi)
{
std::vector<bool>::const_iterator pj = pi + 1;
for (unsigned int j = i + 1; j < N; ++j, ++pj)
if ((*pi == true) && (*pj == true) &&
((vertices[i] - vertices[j]).norm_square() > max_distance_sqr))
max_distance_sqr = (vertices[i] - vertices[j]).norm_square();
}

return std::sqrt(max_distance_sqr);
}
} // namespace


Expand Down Expand Up @@ -154,14 +184,12 @@ LevelSetOKZSolverAdvanceConcentration<dim>::LevelSetOKZSolverAdvanceConcentratio
const VectorType & vel_solution,
const VectorType & vel_solution_old,
const VectorType & vel_solution_old_old,
const double & global_omega_diameter,
const AlignedVector<VectorizedArray<double>> &cell_diameters,
const AffineConstraints<double> & constraints,
const ConditionalOStream & pcout,
const LevelSetOKZSolverAdvanceConcentrationBoundaryDescriptor<dim> &boundary,
const MatrixFree<dim> & matrix_free,
const LevelSetOKZSolverAdvanceConcentrationParameter & parameters,
double & global_max_velocity,
const DiagonalPreconditioner<double> & preconditioner)
: parameters(parameters)
, solution(solution)
Expand All @@ -176,10 +204,9 @@ LevelSetOKZSolverAdvanceConcentration<dim>::LevelSetOKZSolverAdvanceConcentratio
, constraints(constraints)
, pcout(pcout)
, time_stepping(parameters.time)
, global_omega_diameter(global_omega_diameter)
, global_omega_diameter(0.0)
, cell_diameters(cell_diameters)
, boundary(boundary)
, global_max_velocity(global_max_velocity)
, preconditioner(preconditioner)
{}

Expand Down Expand Up @@ -474,6 +501,10 @@ LevelSetOKZSolverAdvanceConcentration<dim>::advance_concentration(const double d
this->time_stepping.set_time_step(dt);
this->time_stepping.next();

if (global_omega_diameter == 0.0)
global_omega_diameter =
diameter_on_coarse_grid(matrix_free.get_dof_handler().get_triangulation());

if (evaluated_convection.size() !=
this->matrix_free.n_cell_batches() *
this->matrix_free.get_n_q_points(parameters.quad_index))
Expand Down
Loading