19 #ifndef _SF_ABSTRACT_VECTOR_H
20 #define _SF_ABSTRACT_VECTOR_H
33 #include "petsc_utils.h"
55 template<
class T,
class S>
79 ltype inp_layout) = 0;
96 virtual void init(T igsize, T ilsize,
int idpn = 1,
ltype ilayout =
unset) = 0;
117 N =
static_cast<T
>(
mesh->
pl.num_global_idx()) *
static_cast<T
>(
dpn);
118 n =
static_cast<T
>(
mesh->
pl.num_algebraic_idx()) *
static_cast<T
>(
dpn);
124 MPI_Allreduce(MPI_IN_PLACE, &N, 1, opencarp::mpi_datatype<T>(), MPI_SUM,
mesh->
comm);
138 return std::tuple<T, T>(N, n);
149 virtual void set(
const vector<T>& idx,
const vector<S>& vals,
const bool additive =
false,
const bool local =
false) = 0;
159 virtual void set(
const vector<T>& idx,
const S val,
const bool additive =
false,
const bool local =
false) = 0;
166 virtual void set(
const S val) = 0;
176 virtual void set(
const T idx,
const S val) = 0;
194 virtual S
get(
const T idx) = 0;
375 virtual S
mag()
const = 0;
382 virtual S
sum()
const = 0;
389 virtual S
min()
const = 0;
463 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm : PETSC_COMM_WORLD;
464 MPI_Comm_rank(comm, &rank);
465 MPI_Comm_size(comm, &size);
466 const MPI_Datatype mpi_t = opencarp::mpi_datatype<T>();
468 T glb_size = this->
gsize();
469 T loc_size = this->
lsize();
476 fd = fopen(file,
"w");
480 MPI_Allreduce(MPI_IN_PLACE, &err, 1, MPI_INT, MPI_MAX, comm);
492 for(T i=0; i<loc_size/this->
dpn; i++) {
493 for(
int j=0; j<this->
dpn; j++)
494 nwr += fprintf(fd,
"%f ", p[i*this->dpn+j]);
495 nwr += fprintf(fd,
"\n");
499 for(
int pid=1; pid < size; pid++)
504 MPI_Recv(&rsize, 1, mpi_t, pid,
SF_MPITAG, comm, &stat);
506 MPI_Recv(wbuff.
data(), rsize*
sizeof(S), MPI_BYTE, pid,
SF_MPITAG, comm, &stat);
508 for(T i=0; i<rsize/this->
dpn; i++) {
509 for(
int j=0; j<this->
dpn; j++)
510 nwr += fprintf(fd,
"%f ", wbuff[i*this->dpn+j]);
511 nwr += fprintf(fd,
"\n");
517 MPI_Send(&loc_size, 1, mpi_t, 0,
SF_MPITAG, comm);
518 MPI_Send(p, loc_size*
sizeof(S), MPI_BYTE, 0,
SF_MPITAG, comm);
522 MPI_Bcast(&nwr, 1, MPI_LONG, 0, comm);
538 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm : PETSC_COMM_WORLD;
539 MPI_Comm_rank(comm, &rank); MPI_Comm_size(comm, &size);
541 long int loc_size = this->
lsize();
545 for(
long int i=0; i<loc_size; i++) buff[i] = p[i];
558 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm : PETSC_COMM_WORLD;
559 int rank; MPI_Comm_rank(comm, &rank);
565 fd = fopen(file.c_str(),
"w");
570 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_INT, MPI_SUM, comm);
573 nwr = this->write_binary<V>(fd);
586 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm : PETSC_COMM_WORLD;
588 size_t loc_size = this->
lsize();
594 for(
size_t i=0; i<loc_size; i++)
605 MPI_Comm comm =
mesh != NULL ?
mesh->
comm : PETSC_COMM_WORLD;
608 int rank; MPI_Comm_rank(comm, &rank);
614 fd = fopen(file.c_str(),
"r");
619 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_INT, MPI_SUM, comm);
622 nrd = read_binary<V>(fd);
634 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm : PETSC_COMM_WORLD;
636 size_t loc_size = this->
lsize();
646 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm : PETSC_COMM_WORLD;
647 int rank; MPI_Comm_rank(comm, &rank);
655 fd = fopen(file.c_str(),
"r");
660 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_INT, MPI_SUM, comm);
677 template<
class T,
class S>
719 template<
class T,
class S>
731 template<
class T,
class S>
743 template<
class T,
class S>
781 const size_t gsize_a,
782 const size_t gsize_b,
785 assert(_registry.
count(spec) == 0);
788 _registry[spec] = sc;
796 for(
size_t i=0; i<nbr_a.
size(); i++)
797 for(
short j=0; j<dpn; j++) idx_a[i*dpn+j] = nbr_a[i]*dpn+j;
799 for(
size_t i=0; i<nbr_b.
size(); i++)
800 for(
short j=0; j<dpn; j++) idx_b[i*dpn+j] = nbr_b[i]*dpn+j;
802 PETSC_CHECK(ISCreateGeneral(PETSC_COMM_WORLD, idx_a.
size(), idx_a.
data(), PETSC_COPY_VALUES, &is_a));
803 PETSC_CHECK(ISCreateGeneral(PETSC_COMM_WORLD, idx_b.
size(), idx_b.
data(), PETSC_COPY_VALUES, &is_b));
805 PETSC_CHECK(ISSetPermutation(is_b));
808 PETSC_CHECK(VecCreateMPI(PETSC_COMM_WORLD, idx_a.
size(), gsize_a*dpn, &a));
809 PETSC_CHECK(VecCreateMPI(PETSC_COMM_WORLD, idx_b.
size(), gsize_b*dpn, &sc->
b_buff));
810 PETSC_CHECK(VecSetFromOptions(a));
811 PETSC_CHECK(VecSetFromOptions(sc->
b_buff));
813 PETSC_CHECK(VecScatterCreate(a, is_a, sc->
b_buff, is_b, &sc->
vec_sc));
815 PETSC_CHECK(VecDestroy(&a));
816 PETSC_CHECK(ISDestroy (&is_a));
817 PETSC_CHECK(ISDestroy (&is_b));
841 assert(_registry.
count(spec) == 0);
844 assert(idx_a.
size() == idx_b.
size());
847 _registry[spec] = sc;
854 T lsize_a = layout_a[rank+1] - layout_a[rank];
855 T lsize_b = layout_b[rank+1] - layout_b[rank];
856 T gsize_a = layout_a[layout_a.
size()-1];
857 T gsize_b = layout_b[layout_a.
size()-1];
861 for(
size_t i=0; i<idx_a.
size(); i++)
862 for(
short j=0; j<dpn; j++) sidx_a[i*dpn+j] = idx_a[i]*dpn+j;
864 for(
size_t i=0; i<idx_b.
size(); i++)
865 for(
short j=0; j<dpn; j++) sidx_b[i*dpn+j] = idx_b[i]*dpn+j;
867 PETSC_CHECK(ISCreateGeneral(PETSC_COMM_WORLD, sidx_a.
size(), sidx_a.
data(), PETSC_COPY_VALUES, &is_a));
868 PETSC_CHECK(ISCreateGeneral(PETSC_COMM_WORLD, sidx_b.
size(), sidx_b.
data(), PETSC_COPY_VALUES, &is_b));
870 PETSC_CHECK(VecCreateMPI(PETSC_COMM_WORLD, lsize_a*dpn, gsize_a*dpn, &a));
871 PETSC_CHECK(VecCreateMPI(PETSC_COMM_WORLD, lsize_b*dpn, gsize_b*dpn, &sc->
b_buff));
872 PETSC_CHECK(VecSetFromOptions(a));
873 PETSC_CHECK(VecSetFromOptions(sc->
b_buff));
875 PETSC_CHECK(VecScatterCreate(a, is_a, sc->
b_buff, is_b, &sc->
vec_sc));
877 PETSC_CHECK(VecDestroy(&a));
878 PETSC_CHECK(ISDestroy (&is_a));
879 PETSC_CHECK(ISDestroy (&is_b));
902 if(_registry.
count(spec))
903 ret = _registry[spec];
914 for(it = _registry.
begin(); it != _registry.
end(); ++it) {
#define SF_MPITAG
the MPI tag when communicating
Classes and algorithms related to the layout of distributed meshes.
Simple utility functions for parallel data.
size_t read_ascii(FILE *fd)
size_t read_binary(std::string file)
virtual void get(const vector< T > &idx, S *out)=0
virtual void apply_scattering(scattering &sc, bool fwd)=0
virtual void operator-=(const abstract_vector< T, S > &vec)=0
virtual void release_ptr(S *&p)=0
virtual std::string to_string() const =0
virtual void operator*=(const abstract_vector< T, S > &vec)=0
virtual T gsize() const =0
size_t write_ascii(const char *file, bool write_header)
virtual void init(T igsize, T ilsize, int idpn=1, ltype ilayout=unset)=0
size_t read_binary(FILE *fd)
virtual void operator/=(const S sca)=0
virtual void forward(abstract_vector< T, S > &out, scattering &sc, bool add=false)=0
virtual bool is_init() const =0
ltype layout
used vector layout (nodal, algebraic, unset)
virtual S * device_ptr()=0
virtual bool equals(const abstract_vector< T, S > &rhs) const =0
virtual void const_release_ptr(const S *&p) const =0
size_t read_ascii(std::string file)
virtual void operator=(const abstract_vector< T, S > &rhs)=0
virtual void deep_copy(const abstract_vector< T, S > &v)=0
size_t write_binary(std::string file)
write binary. Open file descriptor myself.
virtual void get_ownership_range(T &start, T &stop) const =0
virtual S get(const T idx)=0
virtual void set(const vector< T > &idx, const S val, const bool additive=false, const bool local=false)=0
virtual void shallow_copy(const abstract_vector< T, S > &v)=0
std::tuple< T, T > init_common(const meshdata< mesh_int_t, mesh_real_t > &imesh, int idpn, ltype inp_layout)
virtual void add_scaled(const abstract_vector< T, S > &vec, S k)=0
virtual void overshadow(const abstract_vector< T, S > &sub, bool member, int offset, int sz, bool share)=0
virtual void release_device_ptr(S *&p)=0
virtual void set(const S val)=0
virtual ~abstract_vector()=default
virtual void operator+=(const abstract_vector< T, S > &vec)=0
virtual void operator=(const vector< S > &rhs)=0
virtual void set(const T idx, const S val)=0
size_t write_binary(FILE *fd)
Write a vector to HD in binary. File descriptor is already set up.
virtual void backward(abstract_vector< T, S > &out, scattering &sc, bool add=false)=0
virtual T lsize() const =0
virtual void init(const abstract_vector< T, S > &vec)=0
int dpn
d.o.f. per mesh vertex; data is stored node-major (index = node*dpn + component).
virtual const S * const_ptr() const =0
virtual void set(const vector< T > &idx, const vector< S > &vals, const bool additive=false, const bool local=false)=0
virtual void operator*=(const S sca)=0
virtual void finish_assembly()=0
virtual void init(const meshdata< mesh_int_t, mesh_real_t > &imesh, int idpn, ltype inp_layout)=0
const meshdata< mesh_int_t, mesh_real_t > * mesh
the connected mesh
virtual void operator+=(S c)=0
virtual S dot(const abstract_vector< T, S > &v) const =0
overlapping_layout< T > pl
nodal parallel layout
size_t l_numelem
local number of elements
size_t l_numpts
local number of points
size_t g_numelem
global number of elements
MPI_Comm comm
the parallel mesh is defined on a MPI world
The scatterer registry class.
void free_scatterings()
Free the registered scatterings.
scattering * register_scattering(const quadruple< int > spec, const vector< T > &layout_a, const vector< T > &layout_b, const vector< T > &idx_a, const vector< T > &idx_b, const int rank, const int dpn)
Register a scattering.
scattering * register_permutation(const quadruple< int > spec, const vector< T > &nbr_a, const vector< T > &nbr_b, const size_t gsize_a, const size_t gsize_b, const short dpn)
Register a permutation scattering.
scattering * get_scattering(const quadruple< int > spec)
Access an previously registered scattering.
Container for a PETSc VecScatter.
Vec b_buff
A buffer vector which also defines the parallel layout of the "b" side.
void operator()(abstract_vector< T, S > &v, bool fwd)
Apply the scattering on a data vector.
void forward(abstract_vector< T, S > &in, abstract_vector< T, S > &out, bool add=false)
Forward scattering.
VecScatter vec_sc
The scatterer.
void backward(abstract_vector< T, S > &in, abstract_vector< T, S > &out, bool add=false)
Backward scattering.
A vector storing arbitrary data.
size_t size() const
The current size of the vector.
void resize(size_t n)
Resize a vector.
const T * end() const
Pointer to the vector's end.
void assign(InputIterator s, InputIterator e)
Assign a memory range.
const T * begin() const
Pointer to the vector's start.
T * data()
Pointer to the vector's start.
hm_int count(const K &key) const
Check if key exists.
Classes similar to unordered_set and unordered_map, but with better performance.
void treat_file_open_error(const char *file, const char *caller, const int errnum, const bool do_exit, int rank)
treat a file open error by displaying the errnum string interpretation and the caller
bool is_init(const abstract_vector< T, S > *v)
size_t root_read(FILE *fd, vector< V > &vec, MPI_Comm comm)
Read binary data into a vector.
size_t root_read_ascii(FILE *fd, vector< V > &vec, MPI_Comm comm, bool int_data)
Read binary data into a vector.
size_t root_write(FILE *fd, const vector< V > &vec, MPI_Comm comm)
Write vector data binary to disk.
std::intmax_t printable_int(T value)