4 #ifndef _SF_ABSTRACT_VECTOR_H
5 #define _SF_ABSTRACT_VECTOR_H
38 template<
class T,
class S>
62 ltype inp_layout) = 0;
79 virtual void init(T igsize, T ilsize,
int idpn = 1,
ltype ilayout =
unset) = 0;
100 N =
static_cast<T
>(
mesh->
pl.num_global_idx()) *
static_cast<T
>(
dpn);
101 n =
static_cast<T
>(
mesh->
pl.num_algebraic_idx()) *
static_cast<T
>(
dpn);
107 MPI_Allreduce(MPI_IN_PLACE, &N, 1, opencarp::mpi_datatype<T>(), MPI_SUM,
mesh->
comm);
121 return std::tuple<T, T>(N, n);
132 virtual void set(
const vector<T>& idx,
const vector<S>& vals,
const bool additive =
false,
const bool local =
false) = 0;
142 virtual void set(
const vector<T>& idx,
const S val,
const bool additive =
false,
const bool local =
false) = 0;
149 virtual void set(
const S val) = 0;
160 virtual void set(
const T idx,
const S val) = 0;
178 virtual S
get(
const T idx) = 0;
359 virtual S
mag()
const = 0;
366 virtual S
sum()
const = 0;
373 virtual S
min()
const = 0;
447 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm :
SF_COMM;
448 MPI_Comm_rank(comm, &rank);
449 MPI_Comm_size(comm, &size);
450 const MPI_Datatype mpi_t = opencarp::mpi_datatype<T>();
452 T glb_size = this->
gsize();
453 T loc_size = this->
lsize();
460 fd = fopen(file,
"w");
464 MPI_Allreduce(MPI_IN_PLACE, &err, 1, MPI_INT, MPI_MAX, comm);
476 for(T i=0; i<loc_size/this->
dpn; i++) {
477 for(
int j=0; j<this->
dpn; j++)
478 nwr += fprintf(fd,
"%f ", p[i*this->dpn+j]);
479 nwr += fprintf(fd,
"\n");
483 for(
int pid=1; pid < size; pid++)
488 MPI_Recv(&rsize, 1, mpi_t, pid,
SF_MPITAG, comm, &stat);
490 MPI_Recv(wbuff.
data(), rsize*
sizeof(S), MPI_BYTE, pid,
SF_MPITAG, comm, &stat);
492 for(T i=0; i<rsize/this->
dpn; i++) {
493 for(
int j=0; j<this->
dpn; j++)
494 nwr += fprintf(fd,
"%f ", wbuff[i*this->dpn+j]);
495 nwr += fprintf(fd,
"\n");
501 MPI_Send(&loc_size, 1, mpi_t, 0,
SF_MPITAG, comm);
502 MPI_Send(p, loc_size*
sizeof(S), MPI_BYTE, 0,
SF_MPITAG, comm);
506 MPI_Bcast(&nwr, 1, MPI_LONG, 0, comm);
522 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm :
SF_COMM;
523 MPI_Comm_rank(comm, &rank); MPI_Comm_size(comm, &size);
525 long int loc_size = this->
lsize();
529 for(
long int i=0; i<loc_size; i++) buff[i] = p[i];
542 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm :
SF_COMM;
543 int rank; MPI_Comm_rank(comm, &rank);
549 fd = fopen(file.c_str(),
"w");
554 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_INT, MPI_SUM, comm);
557 nwr = this->write_binary<V>(fd);
570 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm :
SF_COMM;
572 size_t loc_size = this->
lsize();
578 for(
size_t i=0; i<loc_size; i++)
592 int rank; MPI_Comm_rank(comm, &rank);
598 fd = fopen(file.c_str(),
"r");
603 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_INT, MPI_SUM, comm);
606 nrd = read_binary<V>(fd);
618 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm :
SF_COMM;
620 size_t loc_size = this->
lsize();
630 MPI_Comm comm = this->mesh != NULL ? this->mesh->
comm :
SF_COMM;
631 int rank; MPI_Comm_rank(comm, &rank);
639 fd = fopen(file.c_str(),
"r");
644 MPI_Allreduce(MPI_IN_PLACE, &error, 1, MPI_INT, MPI_SUM, comm);
661 template<
class T,
class S>
694 template<
class T,
class S>
706 template<
class T,
class S>
718 template<
class T,
class S>
727 void petsc_setup_scattering(scattering& sc,
SF_int lsize_a,
SF_int gsize_a,
762 const size_t gsize_a,
763 const size_t gsize_b,
766 assert(_registry.
count(spec) == 0);
769 _registry[spec] = sc;
776 for(
size_t i=0; i<nbr_a.
size(); i++)
777 for(
short j=0; j<dpn; j++) idx_a[i*dpn+j] = nbr_a[i]*dpn+j;
779 for(
size_t i=0; i<nbr_b.
size(); i++)
780 for(
short j=0; j<dpn; j++) idx_b[i*dpn+j] = nbr_b[i]*dpn+j;
787 petsc_setup_scattering(*sc, idx_a.
size(), gsize_a*dpn, idx_b.
size(), gsize_b*dpn,
true);
809 assert(_registry.
count(spec) == 0);
812 assert(idx_a.
size() == idx_b.
size());
815 _registry[spec] = sc;
820 T lsize_a = layout_a[rank+1] - layout_a[rank];
821 T lsize_b = layout_b[rank+1] - layout_b[rank];
822 T gsize_a = layout_a[layout_a.
size()-1];
823 T gsize_b = layout_b[layout_b.
size()-1];
827 for(
size_t i=0; i<idx_a.
size(); i++)
828 for(
short j=0; j<dpn; j++) sidx_a[i*dpn+j] = idx_a[i]*dpn+j;
830 for(
size_t i=0; i<idx_b.
size(); i++)
831 for(
short j=0; j<dpn; j++) sidx_b[i*dpn+j] = idx_b[i]*dpn+j;
838 petsc_setup_scattering(*sc, lsize_a*dpn, gsize_a*dpn, lsize_b*dpn, gsize_b*dpn,
false);
859 if(_registry.
count(spec))
860 ret = _registry[spec];
871 for(it = _registry.
begin(); it != _registry.
end(); ++it) {
#define SF_COMM
the default SlimFem MPI communicator
opencarp::global_index_t SF_int
Global algebraic index type.
#define SF_MPITAG
the MPI tag when communicating
Classes and algorithms related to the layout of distributed meshes.
Simple utility functions for parallel data.
Starts and stops the linear algebra backend the flavor parameter selects.
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.
Redistributes vector data from indexing "a" to indexing "b".
vector< SF_int > idx_a
the d.o.f. indices of the two sides, which the backends build their scatters from
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.
std::shared_ptr< void > backend_data
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)