Commit 2979a316 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#1053 Provide the backbone of the new test about VertexMatching.

parent a5af34ed
-- Comment lines are introduced by "--".
-- In a section (i.e. within braces), all entries must be separated by a comma.
transient = {
-- Tells which policy is used to describe time evolution.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, {'constant_time_step'})
time_evolution_policy = "constant_time_step",
-- Time at the beginning of the code (in seconds).
-- Expected format: VALUE
-- Constraint: v >= 0.
init_time = 0.,
-- Time step between two iterations, in seconds.
-- Expected format: VALUE
-- Constraint: v > 0.
timeStep = 0.1,
-- Maximum time, if set to zero run a static case.
-- Expected format: VALUE
-- Constraint: v >= 0.
timeMax = 0.
} -- transient
NumberingSubset10 = {
-- Name of the numbering subset (not really used; at the moment I just need one input parameter to ground
-- the possible values to choose elsewhere).
-- Expected format: "VALUE"
name = 'Velocity on fluid',
-- Whether a vector defined on this numbering subset might be used to compute a movemesh. If true, a
-- FEltSpace featuring this numbering subset will compute additional quantities to enable fast computation.
-- This should be false for most numbering subsets, and when it's true the sole unknown involved should be a
-- displacement.
-- Expected format: 'true' or 'false' (without the quote)
do_move_mesh = false
} -- NumberingSubset10
NumberingSubset11 = {
-- Name of the numbering subset (not really used; at the moment I just need one input parameter to ground
-- the possible values to choose elsewhere).
-- Expected format: "VALUE"
name = 'Pressure on fluid',
-- Whether a vector defined on this numbering subset might be used to compute a movemesh. If true, a
-- FEltSpace featuring this numbering subset will compute additional quantities to enable fast computation.
-- This should be false for most numbering subsets, and when it's true the sole unknown involved should be a
-- displacement.
-- Expected format: 'true' or 'false' (without the quote)
do_move_mesh = false
} -- NumberingSubset11
NumberingSubset20 = {
-- Name of the numbering subset (not really used; at the moment I just need one input parameter to ground
-- the possible values to choose elsewhere).
-- Expected format: "VALUE"
name = 'Velocity on solid',
-- Whether a vector defined on this numbering subset might be used to compute a movemesh. If true, a
-- FEltSpace featuring this numbering subset will compute additional quantities to enable fast computation.
-- This should be false for most numbering subsets, and when it's true the sole unknown involved should be a
-- displacement.
-- Expected format: 'true' or 'false' (without the quote)
do_move_mesh = false
} -- NumberingSubset20
NumberingSubset21 = {
-- Name of the numbering subset (not really used; at the moment I just need one input parameter to ground
-- the possible values to choose elsewhere).
-- Expected format: "VALUE"
name = 'Pressure on solid',
-- Whether a vector defined on this numbering subset might be used to compute a movemesh. If true, a
-- FEltSpace featuring this numbering subset will compute additional quantities to enable fast computation.
-- This should be false for most numbering subsets, and when it's true the sole unknown involved should be a
-- displacement.
-- Expected format: 'true' or 'false' (without the quote)
do_move_mesh = false
} -- NumberingSubset21
Unknown1 = {
-- Name of the unknown (used for displays in output).
-- Expected format: "VALUE"
name = 'velocity',
-- Index of the god of dof into which the finite element space is defined.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, {'scalar', 'vectorial'})
nature = 'vectorial'
} -- Unknown1
Unknown2 = {
-- Name of the unknown (used for displays in output).
-- Expected format: "VALUE"
name = 'pressure',
-- Index of the god of dof into which the finite element space is defined.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, {'scalar', 'vectorial'})
nature = 'scalar'
} -- Unknown2
Mesh1 = {
-- Path of the mesh file to use.
-- Expected format: "VALUE"
mesh = '${HOME}/Codes/HappyHeart/Data/Mesh/elasticity_Nx3_Ny2_force_label.mesh',
-- Format of the input mesh.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, {'Ensight', 'Medit'})
format = "Medit",
-- Highest dimension of the input mesh. This dimension might be lower than the one effectively read in the
-- mesh file; in which case Coords will be reduced provided all the dropped values are 0. If not, an
-- exception is thrown.
-- Expected format: VALUE
-- Constraint: v <= 3 and v > 0
dimension = No default value was provided!,
-- Space unit of the mesh.
-- Expected format: VALUE
space_unit = 1.
} -- Mesh1
Mesh2 = {
-- Path of the mesh file to use.
-- Expected format: "VALUE"
mesh = '${HOME}/Codes/HappyHeart/Data/Mesh/elasticity_Nx3_Ny2_force_label.mesh',
-- Format of the input mesh.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, {'Ensight', 'Medit'})
format = "Medit",
-- Highest dimension of the input mesh. This dimension might be lower than the one effectively read in the
-- mesh file; in which case Coords will be reduced provided all the dropped values are 0. If not, an
-- exception is thrown.
-- Expected format: VALUE
-- Constraint: v <= 3 and v > 0
dimension = No default value was provided!,
-- Space unit of the mesh.
-- Expected format: VALUE
space_unit = 1.
} -- Mesh2
-- Domain10
Domain10 = {
-- Index of the geometric mesh upon which the domain is defined (as defined in the present file). Might be
-- left empty if domain not limited to one mesh; at most one value is expected here.
-- Expected format: {VALUE1, VALUE2, ...}
mesh_index = { 1 },
-- List of dimensions encompassed by the domain. Might be left empty if no restriction at all upon
-- dimensions.
-- Expected format: {VALUE1, VALUE2, ...}
-- Constraint: ops_in(v, {0, 1, 2, 3})
dimension_list = { 2 },
-- List of mesh labels encompassed by the domain. Might be left empty if no restriction at all upon mesh
-- labels. This parameter does not make sense if no mesh is defined for the domain.
-- Expected format: {VALUE1, VALUE2, ...}
mesh_label_list = { },
-- List of geometric element types considered in the domain. Might be left empty if no restriction upon
-- these. No constraint is applied at Ops level, as some geometric element types could be added after
-- generation of current input parameter file. Current list is below; if an incorrect value is put there it
-- will be detected a bit later when the domain object is built.
-- The known types when this file was generated are:
-- . Point1
-- . Segment2, Segment3
-- . Triangle3, Triangle6
-- . Quadrangle4, Quadrangle8, Quadrangle9
-- . Tetrahedron4, Tetrahedron10
-- . Hexahedron8, Hexahedron20, Hexahedron27.
-- Expected format: {"VALUE1", "VALUE2", ...}
geometric_element_type_list = { }
}
-- Domain20
Domain20 = {
-- Index of the geometric mesh upon which the domain is defined (as defined in the present file). Might be
-- left empty if domain not limited to one mesh; at most one value is expected here.
-- Expected format: {VALUE1, VALUE2, ...}
mesh_index = { 2 },
-- List of dimensions encompassed by the domain. Might be left empty if no restriction at all upon
-- dimensions.
-- Expected format: {VALUE1, VALUE2, ...}
-- Constraint: ops_in(v, {0, 1, 2, 3})
dimension_list = { 2 },
-- List of mesh labels encompassed by the domain. Might be left empty if no restriction at all upon mesh
-- labels. This parameter does not make sense if no mesh is defined for the domain.
-- Expected format: {VALUE1, VALUE2, ...}
mesh_label_list = { },
-- List of geometric element types considered in the domain. Might be left empty if no restriction upon
-- these. No constraint is applied at Ops level, as some geometric element types could be added after
-- generation of current input parameter file. Current list is below; if an incorrect value is put there it
-- will be detected a bit later when the domain object is built.
-- The known types when this file was generated are:
-- . Point1
-- . Segment2, Segment3
-- . Triangle3, Triangle6
-- . Quadrangle4, Quadrangle8, Quadrangle9
-- . Tetrahedron4, Tetrahedron10
-- . Hexahedron8, Hexahedron20, Hexahedron27.
-- Expected format: {"VALUE1", "VALUE2", ...}
geometric_element_type_list = { }
}
FiniteElementSpace10 = {
-- Index of the god of dof into which the finite element space is defined.
-- Expected format: VALUE
god_of_dof_index = 1,
-- Index of the domain onto which the finite element space is defined. This domain must be unidimensional.
-- Expected format: VALUE
domain_index = 10,
-- List of all unknowns defined in the finite element space. Unknowns here must be defined in this file as
-- an 'Unknown' block; expected name/identifier is the name given there.
-- Expected format: {"VALUE1", "VALUE2", ...}
unknown_list = { 'velocity', 'pressure' },
-- List of the shape function to use for each unknown;
-- Expected format: {"VALUE1", "VALUE2", ...}
shape_function_list = { 'P1', 'P1' },
-- List of the numbering subset to use for each unknown;
-- Expected format: {VALUE1, VALUE2, ...}
numbering_subset_list = { 10, 11 }
} -- FiniteElementSpace10
FiniteElementSpace20 = {
-- Index of the god of dof into which the finite element space is defined.
-- Expected format: VALUE
god_of_dof_index = 2,
-- Index of the domain onto which the finite element space is defined. This domain must be unidimensional.
-- Expected format: VALUE
domain_index = 20,
-- List of all unknowns defined in the finite element space. Unknowns here must be defined in this file as
-- an 'Unknown' block; expected name/identifier is the name given there.
-- Expected format: {"VALUE1", "VALUE2", ...}
unknown_list = { 'velocity', 'pressure' },
-- List of the shape function to use for each unknown;
-- Expected format: {"VALUE1", "VALUE2", ...}
shape_function_list = { 'P1', 'P1' },
-- List of the numbering subset to use for each unknown;
-- Expected format: {VALUE1, VALUE2, ...}
numbering_subset_list = { 20, 21 }
} -- FiniteElementSpace20
Petsc1 = {
-- Absolute tolerance
-- Expected format: VALUE
-- Constraint: v > 0.
absoluteTolerance = 1e-50,
-- gmresStart
-- Expected format: VALUE
-- Constraint: v >= 0
gmresRestart = 200,
-- Maximum iteration
-- Expected format: VALUE
-- Constraint: v > 0
maxIteration = 1000,
-- Preconditioner to use. Must be lu for any direct solver.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, {'lu', 'none'})
preconditioner = 'lu',
-- Relative tolerance
-- Expected format: VALUE
-- Constraint: v > 0.
relativeTolerance = 1e-9,
-- Step size tolerance
-- Expected format: VALUE
-- Constraint: v > 0.
stepSizeTolerance = 1e-8,
-- Solver to use.
-- Expected format: "VALUE"
-- Constraint: ops_in(v, { 'Mumps', 'Umfpack', 'Gmres' })
solver = 'Mumps'
} -- Petsc1
Result = {
-- Directory in which all the results will be written. This path may use the environment variable
-- HAPPY_HEART_RESULT_DIR, which is either provided in user's environment or automatically set to
-- '/Volumes/Data/${USER}/HappyHeart/Results' in HappyHeart initialization step.
-- Expected format: "VALUE"
output_directory = '${HAPPY_HEART_RESULT_DIR}/Test/NonConformInterpolator/FromVertexMatching',
-- Enables to skip some printing in the console. Can be used to WriteSolution every n time.
-- Expected format: VALUE
display_value = 1
} -- Result
This diff is collapsed.
//
// InputParameterList.hpp
// HappyHeart
//
// Created by Sebastien Gilles on 28/07/15.
// Copyright (c) 2015 Inria. All rights reserved.
//
#ifndef HAPPY_HEART_x_TEST_x_OPERATORS_x_CONFORM_PROJECTOR_x_INPUT_PARAMETER_LIST_HPP_
# define HAPPY_HEART_x_TEST_x_OPERATORS_x_CONFORM_PROJECTOR_x_INPUT_PARAMETER_LIST_HPP_
# include "HappyHeart/Utilities/Containers/EnumClass.hpp"
# include "HappyHeart/Core/InputParameterData/InputParameterList.hpp"
# include "HappyHeart/Core/InputParameter/Geometry/Domain.hpp"
# include "HappyHeart/Core/InputParameter/FElt/FEltSpace.hpp"
# include "HappyHeart/Core/InputParameter/FElt/Unknown.hpp"
# include "HappyHeart/Core/InputParameter/FElt/NumberingSubset.hpp"
namespace HappyHeart
{
namespace ConformProjectorNS
{
enum class MeshIndex
{
fluid = 1,
solid = 2
};
enum class DomainIndex
{
fluid = 10,
solid = 20
};
enum class FEltSpaceIndex
{
fluid = 10,
solid = 20
};
enum class UnknownIndex
{
velocity = 1,
pressure = 2
};
enum class SolverIndex
{
solver = 1
};
enum class NumberingSubsetIndex
{
velocity_on_fluid = 10,
pressure_on_fluid = 11,
velocity_on_solid = 20,
pressure_on_solid = 21
};
using InputParameterTuple = std::tuple
<
InputParameter::TimeManager,
InputParameter::NumberingSubset<EnumUnderlyingType(NumberingSubsetIndex::velocity_on_fluid)>,
InputParameter::NumberingSubset<EnumUnderlyingType(NumberingSubsetIndex::pressure_on_fluid)>,
InputParameter::NumberingSubset<EnumUnderlyingType(NumberingSubsetIndex::velocity_on_solid)>,
InputParameter::NumberingSubset<EnumUnderlyingType(NumberingSubsetIndex::pressure_on_solid)>,
InputParameter::Unknown<EnumUnderlyingType(UnknownIndex::velocity)>,
InputParameter::Unknown<EnumUnderlyingType(UnknownIndex::pressure)>,
InputParameter::Mesh<EnumUnderlyingType(MeshIndex::fluid)>,
InputParameter::Mesh<EnumUnderlyingType(MeshIndex::solid)>,
InputParameter::Mesh<EnumUnderlyingType(DomainIndex::fluid)>,
InputParameter::Mesh<EnumUnderlyingType(DomainIndex::solid)>,
InputParameter::FEltSpace<EnumUnderlyingType(FEltSpaceIndex::fluid)>,
InputParameter::FEltSpace<EnumUnderlyingType(FEltSpaceIndex::solid)>,
InputParameter::Petsc<EnumUnderlyingType(SolverIndex::solver)>,
InputParameter::Result
>;
using InputParameterList = InputParameterList<InputParameterTuple>;
} // namespace ConformProjectorNS
} // namespace HappyHeart
#endif // HAPPY_HEART_x_TEST_x_OPERATORS_x_CONFORM_PROJECTOR_x_INPUT_PARAMETER_LIST_HPP_
//
// Model.cpp
// HappyHeart
//
// Created by Sebastien Gilles on 28/07/15.
// Copyright (c) 2015 Inria. All rights reserved.
//
#include "HappyHeart/Core/InputParameter/Result.hpp"
#include "HappyHeart/OperatorInstances/ConformInterpolator/SubsetOrSuperset.hpp"
#include "HappyHeart/Test/Operators/NonConformInterpolator/FromVertexMatching/Model.hpp"
namespace HappyHeart
{
namespace ConformProjectorNS
{
namespace // anonymous
{
void WriteInterpolatorMatrix(const ConformInterpolatorNS::SubsetOrSuperset& interpolator,
const std::string& output_directory,
const Wrappers::Mpi& mpi)
{
const auto& matrix = interpolator.GetInterpolationMatrix();
std::ostringstream oconv;
oconv << output_directory << "/projection_" << interpolator.GetInterpolationMatrix().GetColNumberingSubset().GetUniqueId() << '_'
<< interpolator.GetInterpolationMatrix().GetRowNumberingSubset().GetUniqueId() << ".hhdata";
std::string output_file(oconv.str());
if (mpi.IsRootProcessor())
{
if (FilesystemNS::File::DoExist(output_file))
FilesystemNS::File::Remove(output_file, __FILE__, __LINE__);
}
mpi.Barrier();
matrix.View(mpi, output_file, __FILE__, __LINE__);
}
void WriteConformInterpolatorMatrix(const FEltSpace& orig_felt_space,
const FEltSpace& target_felt_space,
const std::string& output_directory,
const Wrappers::Mpi& mpi)
{
const auto& orig_numbering_subset_list = orig_felt_space.GetNumberingSubsetList();
assert(orig_numbering_subset_list.size() == 1ul);
const auto& target_numbering_subset_list = target_felt_space.GetNumberingSubsetList();
assert(target_numbering_subset_list.size() == 1ul);
const auto& orig_numbering_subset = *orig_numbering_subset_list.back();
const auto& target_numbering_subset = *target_numbering_subset_list.back();
ConformInterpolatorNS::SubsetOrSuperset interpolator12(orig_felt_space,
orig_numbering_subset,
target_felt_space,
target_numbering_subset);
interpolator12.Init();
const auto& matrix = interpolator12.GetInterpolationMatrix();
std::ostringstream oconv;
oconv << output_directory << "/conform_projection_" << orig_numbering_subset.GetUniqueId() << '_'
<< target_numbering_subset.GetUniqueId() << ".hhdata";
std::string output_file(oconv.str());
if (mpi.IsRootProcessor())
{
if (FilesystemNS::File::DoExist(output_file))
FilesystemNS::File::Remove(output_file, __FILE__, __LINE__);
}
mpi.Barrier();
matrix.View(mpi, output_file, __FILE__, __LINE__);
}
} // namespace anonymous
Model::Model(const Wrappers::Mpi& mpi_ptr,
const InputParameterList& input_parameter_data)
: parent(mpi_ptr, input_parameter_data),
output_directory_(Utilities::InputParameterListNS::Extract<InputParameter::Result::OutputDirectory>::Path(input_parameter_data))
{ }
void Model::SupplInitialize(const InputParameterList& input_parameter_data)
{
// static_cast<void>(input_parameter_data);
//
// using interpolator = ConformInterpolatorNS::SubsetOrSuperset;
//
// const auto& god_of_dof = GetGodOfDof(EnumUnderlyingType(MeshIndex::mesh));
//
// const auto& felt_space1 = god_of_dof.GetFEltSpace(1);
// const auto& felt_space2 = god_of_dof.GetFEltSpace(2);
// const auto& felt_space3 = god_of_dof.GetFEltSpace(3);
//
// decltype(auto) numbering_subset_manager = Internal::NumberingSubsetNS::NumberingSubsetManager::GetInstance();
//
// const auto& numbering_subset1 = numbering_subset_manager.GetNumberingSubset(1);
// const auto& numbering_subset2 = numbering_subset_manager.GetNumberingSubset(2);
// const auto& numbering_subset3 = numbering_subset_manager.GetNumberingSubset(3);
//
// const auto& output_directory = GetOutputDirectory();
// const auto& mpi = MpiHappyHeart();
//
// WriteConformInterpolatorMatrix(felt_space1,
// felt_space2,
// output_directory,
// mpi);
// // ------------
// // 1 -> 2
// // ------------
// interpolator_1_2_ = std::make_unique<interpolator>(felt_space1,
// numbering_subset1,
// felt_space2,
// numbering_subset2);
//
// interpolator_1_2_->Init();
//
//
// WriteInterpolatorMatrix(*interpolator_1_2_,
// output_directory,
// mpi);
//
// WriteConformInterpolatorMatrix(felt_space1,