Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F90367610
global_ids_updater.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, Nov 1, 00:45
Size
4 KB
Mime Type
text/x-c
Expires
Sun, Nov 3, 00:45 (2 d)
Engine
blob
Format
Raw Data
Handle
22063168
Attached To
rAKA akantu
global_ids_updater.cc
View Options
/**
* @file global_ids_updater.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Apr 13 2012
* @date last modification: Tue Sep 08 2020
*
* @brief Functions of the GlobalIdsUpdater
*
*
* @section LICENSE
*
* Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "global_ids_updater.hh"
#include "element_synchronizer.hh"
#include "mesh_accessor.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include <numeric>
/* -------------------------------------------------------------------------- */
namespace
akantu
{
UInt
GlobalIdsUpdater
::
updateGlobalIDs
(
UInt
local_nb_new_nodes
)
{
if
(
mesh
.
getCommunicator
().
getNbProc
()
==
1
)
{
return
local_nb_new_nodes
;
}
UInt
total_nb_new_nodes
=
this
->
updateGlobalIDsLocally
(
local_nb_new_nodes
);
if
(
mesh
.
isDistributed
())
{
this
->
synchronizeGlobalIDs
();
}
return
total_nb_new_nodes
;
}
UInt
GlobalIdsUpdater
::
updateGlobalIDsLocally
(
UInt
local_nb_new_nodes
)
{
const
auto
&
comm
=
mesh
.
getCommunicator
();
Int
nb_proc
=
comm
.
getNbProc
();
if
(
nb_proc
==
1
)
{
return
local_nb_new_nodes
;
}
/// resize global ids array
MeshAccessor
mesh_accessor
(
mesh
);
auto
&&
nodes_global_ids
=
mesh_accessor
.
getNodesGlobalIds
();
UInt
old_nb_nodes
=
mesh
.
getNbNodes
()
-
local_nb_new_nodes
;
nodes_global_ids
.
resize
(
mesh
.
getNbNodes
(),
-
1
);
auto
&&
local_or_master_pred
=
[
this
](
auto
&&
n
)
{
return
this
->
mesh
.
isLocalOrMasterNode
(
n
);
};
Vector
<
UInt
>
local_master_nodes
(
2
,
0
);
/// compute the number of global nodes based on the number of old nodes
auto
range_old
=
arange
(
old_nb_nodes
);
local_master_nodes
(
0
)
=
std
::
count_if
(
range_old
.
begin
(),
range_old
.
end
(),
local_or_master_pred
);
/// compute amount of local or master doubled nodes
auto
range_new
=
arange
(
old_nb_nodes
,
mesh
.
getNbNodes
());
local_master_nodes
(
1
)
=
std
::
count_if
(
range_new
.
begin
(),
range_new
.
end
(),
local_or_master_pred
);
auto
starting_index
=
local_master_nodes
(
1
);
comm
.
allReduce
(
local_master_nodes
);
UInt
old_global_nodes
=
local_master_nodes
(
0
);
UInt
total_nb_new_nodes
=
local_master_nodes
(
1
);
if
(
total_nb_new_nodes
==
0
)
{
return
0
;
}
/// set global ids of local and master nodes
comm
.
exclusiveScan
(
starting_index
);
starting_index
+=
old_global_nodes
;
for
(
auto
n
:
range_new
)
{
if
(
mesh
.
isLocalOrMasterNode
(
n
))
{
nodes_global_ids
(
n
)
=
starting_index
;
++
starting_index
;
}
}
mesh_accessor
.
setNbGlobalNodes
(
old_global_nodes
+
total_nb_new_nodes
);
return
total_nb_new_nodes
;
}
void
GlobalIdsUpdater
::
synchronizeGlobalIDs
()
{
this
->
reduce
=
true
;
this
->
synchronizer
.
slaveReductionOnce
(
*
this
,
SynchronizationTag
::
_giu_global_conn
);
#ifndef AKANTU_NDEBUG
for
(
auto
node
:
nodes_flags
)
{
auto
node_flag
=
mesh
.
getNodeFlag
(
node
.
first
);
if
(
node_flag
!=
NodeFlag
::
_pure_ghost
)
{
continue
;
}
auto
n
=
0U
;
for
(
auto
&
pair
:
node
.
second
)
{
if
(
std
::
get
<
1
>
(
pair
)
==
NodeFlag
::
_pure_ghost
)
{
++
n
;
}
}
if
(
n
==
node
.
second
.
size
())
{
AKANTU_DEBUG_WARNING
(
"The node "
<<
n
<<
"is ghost on all the neighboring processors"
);
}
}
#endif
this
->
reduce
=
false
;
this
->
synchronizer
.
synchronizeOnce
(
*
this
,
SynchronizationTag
::
_giu_global_conn
);
}
}
// namespace akantu
Event Timeline
Log In to Comment