1
// Copyright (C) 2008 Anders Logg.
2
// Licensed under the GNU LGPL Version 2.1.
4
// First added: 2008-08-11
5
// Last changed: 2008-09-13
7
#include <dolfin/fem/Assembler.h>
8
#include <dolfin/log/log.h>
9
#include <dolfin/la/Matrix.h>
10
#include <dolfin/la/Vector.h>
11
#include <dolfin/la/solve.h>
12
#include <dolfin/mesh/MeshData.h>
13
#include "Poisson1D.h"
14
#include "Poisson2D.h"
15
#include "Poisson3D.h"
16
#include "HarmonicSmoothing.h"
18
using namespace dolfin;
20
//-----------------------------------------------------------------------------
21
void HarmonicSmoothing::move(Mesh& mesh, Mesh& new_boundary)
23
// Choose form and function space
26
const uint D = mesh.topology().dim();
27
const uint d = mesh.geometry().dim();
31
V = new Poisson1DFunctionSpace(mesh);
32
form = new Poisson1DBilinearForm(*V, *V);
35
V = new Poisson2DFunctionSpace(mesh);
36
form = new Poisson2DBilinearForm(*V, *V);
39
V = new Poisson3DFunctionSpace(mesh);
40
form = new Poisson3DBilinearForm(*V, *V);
43
error("Illegal mesh dimension %d for harmonic mesh smoothing.", D);
48
Assembler::assemble(A, *form);
51
const uint N = mesh.numVertices();
54
// Get array of dofs for boundary vertices
55
const MeshFunction<uint>* vertex_map = new_boundary.data().mesh_function("vertex map");
56
dolfin_assert(vertex_map);
57
const uint num_dofs = vertex_map->size();
58
const uint* dofs = vertex_map->values();
60
// Modify matrix (insert 1 on diagonal)
61
A.ident(num_dofs, dofs);
64
// Solve system for each dimension
65
double* values = new double[num_dofs];
66
double* new_coordinates = new double[d*N];
68
for (uint dim = 0; dim < d; dim++)
70
// Get boundary coordinates
71
for (uint i = 0; i < new_boundary.numVertices(); i++)
72
values[i] = new_boundary.geometry().x(i, dim);
74
// Modify right-hand side
75
b.set(values, num_dofs, dofs);
79
solve(A, x, b, gmres, amg_hypre);
81
// Get new coordinates
82
x.get(new_coordinates + dim*N);
85
// Modify mesh coordinates
86
MeshGeometry& geometry = mesh.geometry();
87
for (uint dim = 0; dim < d; dim++)
88
for (uint i = 0; i < N; i++)
89
geometry.set(i, dim, new_coordinates[dim*N + i]);
95
delete [] new_coordinates;
97
//-----------------------------------------------------------------------------