Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F65111120
ref_subset.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, May 31, 21:44
Size
16 KB
Mime Type
text/x-c++
Expires
Sun, Jun 2, 21:44 (2 d)
Engine
blob
Format
Raw Data
Handle
18005620
Attached To
rLIBMULTISCALE LibMultiScale
ref_subset.cc
View Options
/**
* @file ref_subset.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This file contains the interface of containers of references 4 the
* migration system
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
#include <memory>
/* -------------------------------------------------------------------------- */
#include "lib_continuum.hh"
#include "lib_dd.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "ref_subset.hh"
#include "trace_atom.hh"
#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
declareSentRefs
(
MapRefToUInt
&
sent_refs
,
MapUIntToRefList
&
sent_reverse
)
{
DUMP
(
"declare refs sent for subset "
<<
container
.
getID
(),
DBG_INFO
);
// clear maps
sent
.
clear
();
sent_indexes
.
clear
();
MapRefToUInt
sent_index_in_subset
;
// loop over subset refs
if
constexpr
(
is_subset
)
{
for
(
auto
&&
[
i
,
ref
]
:
enumerate
(
container
))
{
// get the reference to the ref "i" in subset
if
(
sent_refs
.
count
(
ref
)
>
0
)
{
if
(
sent_refs
[
ref
]
==
UINT_MAX
)
continue
;
sent_index_in_subset
[
ref
]
=
i
;
this
->
holes
.
push_back
(
i
);
}
}
}
// loop over the sent refs to build ordered buffer list
UInt
idx
;
for
(
auto
&&
[
proc
,
listsent
]
:
sent_reverse
)
{
for
(
auto
&&
ref
:
listsent
)
{
if
(
is_subset
and
not
sent_index_in_subset
.
count
(
ref
))
continue
;
if
constexpr
(
not
is_subset
)
{
idx
=
ref
.
getIndex
();
}
else
{
idx
=
sent_index_in_subset
[
ref
];
}
sent
[
proc
].
push_back
(
ref
);
sent_indexes
[
proc
].
push_back
(
idx
);
IF_REF_TRACED
(
ref
,
"traced ref sent to "
<<
proc
<<
" for container "
<<
container
.
getID
());
}
for
(
auto
&&
[
proc
,
list_sent
]
:
sent
)
{
DUMP
(
"I am supposed to send "
<<
list_sent
.
size
()
<<
" refs to proc "
<<
proc
<<
" for subset "
<<
container
.
getID
()
<<
"("
<<
subset_id
<<
")"
,
DBG_INFO
);
}
}
}
/* ------------------------------------------------------------------------ */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
declareRecvRefs
(
MapRefToUInt
&
masks
,
MapUIntToRefList
&
recv_refs
)
{
DUMP
(
"declare refs received for subset "
<<
container
.
getID
(),
DBG_INFO
);
UInt
mask
[[
gnu
::
unused
]]
=
1
<<
subset_id
;
// clear maps
recv
.
clear
();
recv_indexes
.
clear
();
auto
register_newref
=
[
&
](
auto
proc
,
auto
new_index
,
auto
&
ref
)
{
IF_REF_TRACED
(
ref
,
"traced ref received from "
<<
proc
<<
" for container "
<<
container
.
getID
()
<<
" (index is now "
<<
new_index
<<
")"
);
recv_indexes
[
proc
].
push_back
(
new_index
);
recv
[
proc
].
push_back
(
ref
);
};
for
(
auto
&&
[
proc
,
recvlist
]
:
recv_refs
)
{
for
(
auto
&&
ref
:
recvlist
)
{
if
constexpr
(
is_subset
)
{
// check if concerned with ref => register
if
(
masks
[
ref
]
&
mask
)
{
UInt
new_index
;
// find a new index (if possible within holes)
if
(
!
this
->
holes
.
empty
())
{
new_index
=
this
->
holes
.
back
();
container
.
get
(
new_index
)
=
ref
;
this
->
holes
.
pop_back
();
}
else
{
new_index
=
container
.
size
();
container
.
push_back
(
ref
);
}
register_newref
(
proc
,
new_index
,
ref
);
}
}
else
{
register_newref
(
proc
,
ref
.
getIndex
(),
ref
);
}
}
}
for
(
auto
&&
[
proc
,
recvlist
]
:
recv_indexes
)
{
DUMP
(
"I am supposed to recv "
<<
recvlist
.
size
()
<<
" refs from proc "
<<
proc
<<
" for subset "
<<
container
.
getID
()
<<
"("
<<
subset_id
<<
")"
,
DBG_INFO
);
}
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
buildMasksForSentRefs
(
MapRefToUInt
&
masks
)
{
if
constexpr
(
not
is_subset
)
return
;
UInt
mask
=
1
<<
subset_id
;
for
(
auto
&&
[
proc
,
reflist
]
:
sent
)
{
UInt
nRefs
=
reflist
.
size
();
for
(
UInt
i
=
0
;
i
<
nRefs
;
++
i
)
{
Ref
ref
=
reflist
[
i
];
if
(
!
masks
.
count
(
ref
))
masks
[
ref
]
=
mask
;
else
masks
[
ref
]
|=
mask
;
}
}
}
/* ----------------------------------------------------------------------- */
// template <typename Ref, bool is_subset>
// void RefSubset<Ref, is_subset>::packAttachedData(
// LAMMPS_NS::PackBuffer &buffer) {
// LM_TOIMPLEMENT;
// // for (auto &&[proc, listsent] : sent_indexes) {
// // if (proc == UINT_MAX)
// // continue;
// // for (auto &&[i, sent_index] : enumerate(listsent)) {
// // if (this->attached_objects.size() > 0)
// // DUMP(container.getID()
// // << " prepares to pack to proc " << proc << " subset index
// "
// // << i << " ref index " << sent_index,
// // DBG_MESSAGE);
// // for (auto &&[ptr, att_obj] : this->attached_objects) {
// // DUMP("prepares to pack obj " << att_obj->getID(), DBG_MESSAGE);
// // att_obj->packData(sent_index, buffer[proc], proc, true);
// // }
// // }
// // }
// }
/* ------------------------------------------------------------------------ */
// template <typename Ref, bool is_subset>
// void RefSubset<Ref, is_subset>::unpackAttachedData(
// LAMMPS_NS::PackBuffer &buffer) {
// LM_TOIMPLEMENT;
// // for (auto &&[proc, listrecv] : recv_indexes) {
// // if (proc == UINT_MAX)
// // continue;
// // for (auto &&[i, recv_index] : enumerate(listrecv)) {
// // if (CHECK_REF_TRACED(recv[proc][i]))
// // DUMP(container.getID()
// // << " prepares to unpack from proc " << proc << " subset
// // index "
// // << i << " ref index " << recv_index,
// // DBG_MESSAGE);
// // for (auto &&[ptr, att_obj] : this->attached_objects) {
// // if (CHECK_REF_TRACED(recv[proc][i]))
// // DUMP("prepares to pack obj " << att_obj->getID(),
// DBG_MESSAGE);
// // att_obj->unpackData(recv_index, buffer[proc], proc,
// // CHECK_REF_TRACED(recv[proc][i]));
// // }
// // }
// // }
// }
/* ----------------------------------------------------------------------- */
#define printInfoAttachedValue(mess, att_obj, container, i_src) \
{ \
DUMP(container.getID() << "[" << i_src << "] = " << container.get(i_src) \
<< " attached:" << att_obj->getID() << ": " \
<< att_obj->getV().row(i_src) << " ### " << mess, \
DBG_DETAIL); \
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
packData
(
Ref
&
ref
,
LAMMPS_NS
::
PackBuffer
&
buffer
,
bool
verbose
)
{
auto
index
=
this
->
getRefIndex
(
ref
);
if
(
index
==
-
1
)
{
LM_FATAL
(
this
->
getID
()
<<
": this should not happen:"
<<
ref
);
}
for
(
auto
&&
[
ID
,
att_obj
]
:
this
->
attached_objects
)
{
att_obj
->
packData
(
index
,
buffer
,
verbose
);
if
(
CHECK_REF_TRACED
(
ref
))
{
if
(
auto
ptr
=
dynamic_cast
<
AttachedVector
<
Real
>
*>
(
att_obj
.
get
()))
{
printInfoAttachedValue
(
"packing"
,
ptr
,
container
,
index
);
}
}
}
if
constexpr
(
is_subset
)
{
DUMP
(
this
->
getID
()
<<
": adding the hole"
<<
index
,
DBG_DETAIL
);
this
->
holes
.
push_back
(
index
);
this
->
reverse_index_map
.
erase
(
ref
);
}
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
unpackData
(
Ref
&
ref
,
LAMMPS_NS
::
PackBuffer
&
buffer
,
bool
verbose
)
{
auto
index
=
this
->
getRefIndex
(
ref
);
if
constexpr
(
is_subset
)
{
if
(
index
!=
-
1
)
LM_FATAL
(
"this should not happen: found "
<<
container
.
getID
()
<<
"["
<<
index
<<
"] = "
<<
ref
);
if
(
this
->
holes
.
size
()
>
0
)
{
index
=
this
->
holes
.
back
();
this
->
holes
.
pop_back
();
}
else
{
index
=
this
->
container
.
size
();
this
->
container
.
resize
(
index
+
1
);
}
this
->
container
.
get
(
index
)
=
ref
;
this
->
reverse_index_map
[
ref
]
=
index
;
}
for
(
auto
&&
[
ID
,
att_obj
]
:
this
->
attached_objects
)
{
att_obj
->
unpackData
(
index
,
buffer
,
verbose
);
if
(
CHECK_REF_TRACED
(
ref
))
{
if
(
auto
ptr
=
dynamic_cast
<
AttachedVector
<
Real
>
*>
(
att_obj
.
get
()))
{
printInfoAttachedValue
(
"unpacking"
,
ptr
,
container
,
index
);
}
}
}
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
translateMovingReference
(
Ref
&
src
,
Ref
&
dst
)
{
if
constexpr
(
not
is_subset
)
return
;
// get the index of the reference to be shifted in the subset
auto
i_src
=
this
->
getRefIndex
(
src
);
// check if the moved(src) ref atom is in this subset
// if not I am not concerned by this change
if
(
i_src
==
-
1
)
{
DUMP
(
"could not find "
<<
src
<<
" in "
<<
this
->
container
.
getID
(),
DBG_MESSAGE
);
return
;
}
// if (CHECK_REF_TRACED(container.get(i_src))) {
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
if
(
auto
ptr
=
dynamic_cast
<
AttachedVector
<
Real
>
*>
(
att_obj
.
get
()))
{
printInfoAttachedValue
(
"before translate"
,
ptr
,
container
,
i_src
);
}
}
//}
// check if the ref atom of the destination is in this subset
// This ref atom points certainly to an atom that left the processor
// if it is in this subset then I have a hole to register
container
.
get
(
i_src
)
=
dst
;
this
->
reverse_index_map
.
erase
(
src
);
this
->
reverse_index_map
[
dst
]
=
i_src
;
// if (CHECK_REF_TRACED(container.get(i_src))) {
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
if
(
auto
ptr
=
dynamic_cast
<
AttachedVector
<
Real
>
*>
(
att_obj
.
get
()))
{
printInfoAttachedValue
(
"after translate"
,
ptr
,
container
,
i_src
);
}
}
//}
}
/* --------------------------------------------------------------------------
*/
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
fillRemainingHoles
()
{
if
constexpr
(
not
is_subset
)
return
;
std
::
sort
(
this
->
holes
.
begin
(),
this
->
holes
.
end
());
// checks if there are remaining holes for which we need to displace
// the references order and attached values
while
(
!
this
->
holes
.
empty
())
{
UInt
index
=
this
->
holes
.
back
();
this
->
holes
.
pop_back
();
DUMP
(
"filling hole: "
<<
index
<<
" container size was: "
<<
container
.
size
(),
DBG_DETAIL
);
UInt
nRefs
=
container
.
size
();
if
(
index
==
nRefs
-
1
)
// container.resize(nRefs - 1);
resize
(
nRefs
-
1
);
else
moveLastReferenceToHole
(
index
);
DUMP
(
"filling hole: "
<<
index
<<
" container size: "
<<
container
.
size
(),
DBG_DETAIL
);
}
}
/* ---------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
moveReference
(
UInt
i_src
,
UInt
i_dest
)
{
if
(
i_src
==
i_dest
)
return
;
IF_REF_TRACED
(
container
.
get
(
i_src
),
" = "
<<
container
.
getID
()
<<
"["
<<
i_src
<<
"]: "
<<
" traced ref moved from index "
<<
i_src
<<
" to index "
<<
i_dest
<<
" for container "
<<
container
.
getID
());
if
(
CHECK_REF_TRACED
(
container
.
get
(
i_src
)))
{
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
if
(
auto
ptr
=
dynamic_cast
<
AttachedVector
<
Real
>
*>
(
att_obj
.
get
()))
{
printInfoAttachedValue
(
"before moving "
,
ptr
,
container
,
i_src
);
}
}
}
if
constexpr
(
is_subset
)
container
.
get
(
i_dest
)
=
container
.
get
(
i_src
);
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
att_obj
->
moveAttachedValues
(
i_src
,
i_dest
);
if
(
CHECK_REF_TRACED
(
container
.
get
(
i_dest
)))
{
if
(
auto
ptr
=
dynamic_cast
<
AttachedVector
<
Real
>
*>
(
att_obj
.
get
()))
{
printInfoAttachedValue
(
"after moving attached "
,
ptr
,
container
,
i_dest
);
}
}
}
}
/* ------------------------------------------------------------------------ */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
moveLastReferenceToHole
(
UInt
i_dest
)
{
if
constexpr
(
not
is_subset
)
return
;
UInt
nRefs
=
container
.
size
();
if
(
nRefs
-
1
==
i_dest
)
return
;
if
(
i_dest
>
nRefs
-
1
)
{
int
a
=
1
;
while
(
a
)
{
}
}
moveReference
(
nRefs
-
1
,
i_dest
);
// container.resize(nRefs-1);
resize
(
nRefs
-
1
);
}
/* --------------------------------------------------------------------------
*/
template
<
typename
Ref
,
bool
is_subset
>
UInt
RefSubset
<
Ref
,
is_subset
>::
resize
(
UInt
sz
)
{
if
constexpr
(
is_subset
)
{
if
(
sz
==
UInt
(
-
1
))
LM_FATAL
(
"this should not happen"
);
container
.
resize
(
sz
);
}
else
{
if
(
sz
!=
UInt
(
-
1
))
LM_FATAL
(
"this should not happen"
);
sz
=
container
.
size
();
}
DUMP
(
container
.
getID
()
<<
" resizes from "
<<
container
.
size
()
<<
" to "
<<
sz
,
DBG_INFO
);
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
att_obj
->
resize
(
sz
);
}
return
sz
;
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
bool
RefSubset
<
Ref
,
is_subset
>::
is_hole
(
UInt
index
)
{
auto
it
=
std
::
find
(
this
->
holes
.
begin
(),
this
->
holes
.
end
(),
index
);
bool
is_hole
(
it
!=
this
->
holes
.
end
());
return
is_hole
;
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
int
RefSubset
<
Ref
,
is_subset
>::
getRefIndex
(
Ref
&
ref
)
{
if
constexpr
(
is_subset
)
{
if
(
this
->
reverse_index_map
.
count
(
ref
))
{
return
this
->
reverse_index_map
[
ref
];
}
// return reverse_index_map[ref];
// for (auto &&[i, e] : enumerate(container)) {
// if ((not this->is_hole(i)) and e == ref)
// return i;
// }
return
-
1
;
}
return
ref
.
getIndex
();
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
fillMasks
(
MapRefToUInt
&
masks
)
{
for
(
auto
&&
[
i
,
e
]
:
enumerate
(
container
))
{
if
(
masks
.
count
(
e
)
!=
0
)
masks
[
e
]
|=
this
->
mask
();
else
masks
[
e
]
=
this
->
mask
();
if
constexpr
(
is_subset
)
reverse_index_map
[
e
]
=
i
;
}
}
/* ----------------------------------------------------------------------- */
#define DECLARE_REF_SUBSET(n, data, obj) \
template class RefSubset<ContainerArray<typename BOOST_PP_TUPLE_ELEM( \
3, 0, obj)::ContainerPoints::Ref>, \
true>; \
template class RefSubset< \
typename BOOST_PP_TUPLE_ELEM(3, 0, obj)::ContainerPoints, false>;
BOOST_PP_SEQ_FOR_EACH
(
DECLARE_REF_SUBSET
,
f
,
LIST_ATOM_MODEL
)
BOOST_PP_SEQ_FOR_EACH
(
DECLARE_REF_SUBSET
,
f
,
LIST_DD_MODEL
)
BOOST_PP_SEQ_FOR_EACH
(
DECLARE_REF_SUBSET
,
f
,
LIST_CONTINUUM_MODEL
)
#undef DECLARE_REF_SUBSET
__END_LIBMULTISCALE__
Event Timeline
Log In to Comment