Skip to content

Commit

Permalink
Initial implementation of virtual transformed mesh for transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
fdkong committed Jul 9, 2020
1 parent d1238a6 commit 23815c2
Show file tree
Hide file tree
Showing 4 changed files with 390 additions and 411 deletions.
6 changes: 6 additions & 0 deletions framework/include/transfers/MultiAppFieldTransfer.h
Expand Up @@ -52,4 +52,10 @@ class MultiAppFieldTransfer : public MultiAppTransfer
virtual std::vector<VariableName> getFromVarNames() const = 0;
/// Virtual function defining variables to transfer to
virtual std::vector<AuxVariableName> getToVarNames() const = 0;

void computeTransformation(MooseMesh & mesh,
std::unordered_map<dof_id_type, Point> & transformation);

Real _shrink_gap_width;
MooseEnum _shrink_mesh;
};
18 changes: 18 additions & 0 deletions framework/include/transfers/MultiAppInterpolationTransfer.h
Expand Up @@ -14,6 +14,10 @@

#include "libmesh/mesh_base.h"

#include "libmesh/meshfree_interpolation.h"
#include "libmesh/system.h"
#include "libmesh/radial_basis_interpolation.h"

// Forward declarations
class MultiAppInterpolationTransfer;

Expand Down Expand Up @@ -46,6 +50,20 @@ class MultiAppInterpolationTransfer : public MultiAppConservativeTransfer
const MeshBase::const_node_iterator & nodes_begin,
const MeshBase::const_node_iterator & nodes_end);

void
fillSourceInterpolationPoints(FEProblemBase & from_problem,
MooseVariableFEBase & from_var,
Point & from_app_position,
std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> & idi);

void interpolateTargetPoints(FEProblemBase & to_problem,
MooseVariableFEBase & to_var,
NumericVector<Real> & to_solution,
Point & to_app_position,
std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> & idi);

subdomain_id_type subdomainIDNode(MooseMesh & mesh, Node & node);

unsigned int _num_points;
Real _power;
MooseEnum _interp_type;
Expand Down
73 changes: 72 additions & 1 deletion framework/src/transfers/MultiAppFieldTransfer.C
Expand Up @@ -24,11 +24,20 @@ InputParameters
MultiAppFieldTransfer::validParams()
{
InputParameters params = MultiAppTransfer::validParams();
params.addParam<Real>(
"shrink_gap_width",
0,
"gap width with which we want to temporarily shrink mesh in transfering solution");

MooseEnum shrink_type("SOURCE TARGET", "SOURCE");
params.addParam<MooseEnum>("shrink_mesh", shrink_type, "Which mesh we want to shrink");
return params;
}

MultiAppFieldTransfer::MultiAppFieldTransfer(const InputParameters & parameters)
: MultiAppTransfer(parameters)
: MultiAppTransfer(parameters),
_shrink_gap_width(getParam<Real>("shrink_gap_width")),
_shrink_mesh(getParam<MooseEnum>("shrink_mesh"))
{
}

Expand All @@ -43,6 +52,68 @@ MultiAppFieldTransfer::initialSetup()
variableIntegrityCheck(from_var);
}

void
MultiAppFieldTransfer::computeTransformation(
MooseMesh & mesh, std::unordered_map<dof_id_type, Point> & transformation)
{
auto & libmesh_mesh = mesh.getMesh();

auto & subdomainids = mesh.meshSubdomains();

int max_subdomain_id = 0;

for (auto subdomain_id : subdomainids)
{
max_subdomain_id = max_subdomain_id > subdomain_id ? max_subdomain_id : subdomain_id;
}

max_subdomain_id += 1;

std::unordered_map<dof_id_type, Point> subdomain_centers;
std::unordered_map<dof_id_type, dof_id_type> nelems;

for (auto & elem :
as_range(libmesh_mesh.local_elements_begin(), libmesh_mesh.local_elements_end()))
{
subdomain_centers[max_subdomain_id] += elem->centroid();
nelems[max_subdomain_id] += 1;

auto subdomain = elem->subdomain_id();

if (subdomain == Moose::INVALID_BLOCK_ID)
mooseError("block is invalid");

subdomain_centers[subdomain] += elem->centroid();

nelems[subdomain] += 1;
}

comm().sum(subdomain_centers);

comm().sum(nelems);

subdomain_centers[max_subdomain_id] /= nelems[max_subdomain_id];

for (auto subdomain_id : subdomainids)
{
subdomain_centers[subdomain_id] /= nelems[subdomain_id];
}

transformation.clear();
for (auto subdomain_id : subdomainids)
{
transformation[subdomain_id] =
subdomain_centers[max_subdomain_id] - subdomain_centers[subdomain_id];

auto norm = transformation[subdomain_id].norm();

if (norm > 1e-10)
transformation[subdomain_id] /= norm;

transformation[subdomain_id] *= _shrink_gap_width;
}
}

void
MultiAppFieldTransfer::transferDofObject(libMesh::DofObject * to_object,
libMesh::DofObject * from_object,
Expand Down

0 comments on commit 23815c2

Please sign in to comment.