dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #11223
linking problems with dolfin/fem/assemble.h
Hello everyone!
Since I post for the first time on the M-list, I thank you all for the
fenics suite.
I am developing some code in C++, and I use dolfin in order to solve
some BVP problem. I did include dolfin.h and two forms compiled with
ffc in each file. I had a trouble when linking my stuff.
I am no C++ expert, so I don't know wether it is because of me or not.
I did use the recent revision number 5349 (result of `hg id -n`).
When compiling my stuff, I did have some _linking_ problems like:
(...snip...)
Output.o: in function «
boost::numeric::ublas::compressed_matrix<double,
boost::numeric::ublas::basic_row_major<unsigned long, long>, 0ul,
boost::numeric::ublas::unbounded_array<unsigned long,
std::allocator<unsigned long> >,
boost::numeric::ublas::unbounded_array<double, std::allocator<double>
> >::size1() const»:
$PREFIX/local/include/dolfin/fem/assemble.h:89: multiple definitions
of « dolfin::assemble_system(dolfin::GenericMatrix&,
dolfin::GenericVector&, dolfin::Form const&, dolfin::Form const&,
std::vector<dolfin::DirichletBC const*,
std::allocator<dolfin::DirichletBC const*> >&,
dolfin::MeshFunction<unsigned int> const*,
dolfin::MeshFunction<unsigned int> const*,
dolfin::MeshFunction<unsigned int> const*, dolfin::GenericVector
const*, bool)»
main.o:/homes/tgax/local/include/dolfin/fem/assemble.h:89: first definition here
(...snip...)
In other words, I have troubles with function assemble_system in file
dolfin/fem/assemble.h .
I had a look at the assemble.h file. It is a file with code calling
methods from the Assembler class (defined in files
dolfin/fem/Assembler.*).
A `nm` on my *.o did show undefined symbols for function
assemble_system, in several object files. Assembler::assemble_system
were OK.
The code from assemble.h seems to be compiled in several of my object
files, so the linker just cannot link.
In order to solve this, I did split dolfin/fem/assemble.h into a .cpp
and a real header file. The SConstruct process automatically compiles
assemble.cpp, and the link could be done to my program.
I don't know if it is a real problem of dolfin, or if I did something
wrong, but I wanted to let you known. What do you think?
With the best regards,
Thomas G.
13,15d12
< #ifndef __ASSEMBLE_H
< #define __ASSEMBLE_H
<
27c24,27
< bool reset_tensor);
---
> bool reset_tensor=true)
> {
> Assembler::assemble(A, a, reset_tensor);
> }
33c33,36
< bool reset_tensor);
---
> bool reset_tensor=true)
> {
> Assembler::assemble(A, a, sub_domain, reset_tensor);
> }
41c44,47
< bool reset_tensor);
---
> bool reset_tensor=true)
> {
> Assembler::assemble(A, a, cell_domains, exterior_facet_domains, interior_facet_domains);
> }
49c55,58
< bool reset_tensors);
---
> bool reset_tensors=true)
> {
> Assembler::assemble_system(A, b, a, L, bc, reset_tensors);
> }
57c66,69
< bool reset_tensors);
---
> bool reset_tensors=true)
> {
> Assembler::assemble_system(A, b, a, L, bcs, reset_tensors);
> }
69c81,86
< bool reset_tensors);
---
> bool reset_tensors=true)
> {
> Assembler::assemble_system(A, b, a, L, bcs,
> cell_domains, exterior_facet_domains, interior_facet_domains,
> x0, reset_tensors);
> }
75c92,98
< bool reset_tensor);
---
> bool reset_tensor=true)
> {
> if (a.rank() != 0) error("Unable to assemble, form is not scalar.");
> Scalar s;
> Assembler::assemble(s, a, reset_tensor);
> return s;
> }
80c103,109
< bool reset_tensor);
---
> bool reset_tensor=true)
> {
> if (a.rank() != 0) error("Unable to assemble, form is not scalar.");
> Scalar s;
> Assembler::assemble(s, a, sub_domain, reset_tensor);
> return s;
> }
87,88c116,122
< bool reset_tensor);
< }
---
> bool reset_tensor=true)
> {
> if (a.rank() != 0) error("Unable to assemble, form is not scalar.");
> Scalar s;
> Assembler::assemble(s, a, cell_domains, exterior_facet_domains, interior_facet_domains, reset_tensor);
> return s;
> }
90c124
< #endif
---
> }
// Copyright (C) 2007-2008 Anders Logg.
// Licensed under the GNU LGPL Version 2.1.
//
// Modified by Garth N. Wells, 2008.
//
// First added: 2007-01-17
// Last changed: 2008-11-16
//
// This file duplicates the Assembler::assemble* functions in
// namespace dolfin, and adds special versions returning the value
// directly for scalars. For documentation, refer to Assemble.h.
#include <dolfin/log/log.h>
#include <dolfin/la/Scalar.h>
#include "Form.h"
#include "Assembler.h"
#include "assemble.h"
namespace dolfin
{
using namespace dolfin;
//--- Copies of assembly functions in Assembler.h ---
/// Assemble tensor
void assemble(GenericTensor& A,
const Form& a,
bool reset_tensor=true)
{
Assembler::assemble(A, a, reset_tensor);
}
/// Assemble tensor on sub domain
void assemble(GenericTensor& A,
const Form& a,
const SubDomain& sub_domain,
bool reset_tensor=true)
{
Assembler::assemble(A, a, sub_domain, reset_tensor);
}
/// Assemble tensor on sub domains
void assemble(GenericTensor& A,
const Form& a,
const MeshFunction<uint>* cell_domains,
const MeshFunction<uint>* exterior_facet_domains,
const MeshFunction<uint>* interior_facet_domains,
bool reset_tensor=true)
{
Assembler::assemble(A, a, cell_domains, exterior_facet_domains, interior_facet_domains);
}
/// Assemble system (A, b) and apply Dirichlet boundary condition
void assemble_system(GenericMatrix& A,
GenericVector& b,
const Form& a,
const Form& L,
const DirichletBC& bc,
bool reset_tensors=true)
{
Assembler::assemble_system(A, b, a, L, bc, reset_tensors);
}
/// Assemble system (A, b) and apply Dirichlet boundary conditions
void assemble_system(GenericMatrix& A,
GenericVector& b,
const Form& a,
const Form& L,
std::vector<const DirichletBC*>& bcs,
bool reset_tensors=true)
{
Assembler::assemble_system(A, b, a, L, bcs, reset_tensors);
}
/// Assemble system (A, b) on sub domains and apply Dirichlet boundary conditions
void assemble_system(GenericMatrix& A,
GenericVector& b,
const Form& a,
const Form& L,
std::vector<const DirichletBC*>& bcs,
const MeshFunction<uint>* cell_domains,
const MeshFunction<uint>* exterior_facet_domains,
const MeshFunction<uint>* interior_facet_domains,
const GenericVector* x0,
bool reset_tensors=true)
{
Assembler::assemble_system(A, b, a, L, bcs,
cell_domains, exterior_facet_domains, interior_facet_domains,
x0, reset_tensors);
}
//--- Specialized versions for scalars ---
/// Assemble scalar
double assemble(const Form& a,
bool reset_tensor=true)
{
if (a.rank() != 0) error("Unable to assemble, form is not scalar.");
Scalar s;
Assembler::assemble(s, a, reset_tensor);
return s;
}
/// Assemble scalar on sub domain
double assemble(const Form& a,
const SubDomain& sub_domain,
bool reset_tensor=true)
{
if (a.rank() != 0) error("Unable to assemble, form is not scalar.");
Scalar s;
Assembler::assemble(s, a, sub_domain, reset_tensor);
return s;
}
/// Assemble scalar on sub domains
double assemble(const Form& a,
const MeshFunction<uint>* cell_domains,
const MeshFunction<uint>* exterior_facet_domains,
const MeshFunction<uint>* interior_facet_domains,
bool reset_tensor=true)
{
if (a.rank() != 0) error("Unable to assemble, form is not scalar.");
Scalar s;
Assembler::assemble(s, a, cell_domains, exterior_facet_domains, interior_facet_domains, reset_tensor);
return s;
}
}
Follow ups