Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F63164827
domain_multiscale.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
Sat, May 18, 04:49
Size
15 KB
Mime Type
text/x-c
Expires
Mon, May 20, 04:49 (2 d)
Engine
blob
Format
Raw Data
Handle
17739669
Attached To
rLIBMULTISCALE LibMultiScale
domain_multiscale.cc
View Options
/**
* @file domain_multiscale.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Wed Jul 02 16:25:38 2014
*
* @brief This is a meta domain whose purpose is to handle other domains
*
* @section LICENSE
*
* Copyright INRIA and CEA
*
* The LibMultiScale is a C++ parallel framework for the multiscale
* coupling methods dedicated to material simulations. This framework
* provides an API which makes it possible to program coupled simulations
* and integration of already existing codes.
*
* This Project was initiated in a collaboration between INRIA Futurs Bordeaux
* within ScAlApplix team and CEA/DPTA Ile de France.
* The project is now continued at the Ecole Polytechnique Fédérale de Lausanne
* within the LSMS/ENAC laboratory.
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*
*/
/* -------------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
#include "action_interface.hh"
#include "coupler_manager.hh"
#include "domain_multiscale.hh"
#include "factory_multiscale.hh"
#include "filter_interface.hh"
#include "geometry_manager.hh"
#include "lib_continuum.hh"
#include "lib_dd.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "lm_communicator.hh"
#include "lm_parser.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
DomainMultiScale
::~
DomainMultiScale
()
{}
/* -------------------------------------------------------------------------- */
DomainMultiScale
::
DomainMultiScale
()
:
LMObject
(
"DomainMultiscale"
)
{}
/* -------------------------------------------------------------------------- */
void
DomainMultiScale
::
coupling
(
CouplingStage
stage
)
{
#ifdef LIBMULTISCALE_USE_EPSN
if
(
epsn_itfc
->
isNodeInitialized
())
epsn_itfc
->
beginTask
(
"updatecoupling"
);
#endif
CouplerManager
::
getManager
().
coupling
(
stage
);
#ifdef LIBMULTISCALE_USE_EPSN
if
(
epsn_itfc
->
isNodeInitialized
())
epsn_itfc
->
endTask
(
"updatecoupling"
);
#endif
}
/* -------------------------------------------------------------------------- */
UInt
DomainMultiScale
::
build
(
const
std
::
string
&
config
)
{
Parser
::
parseConfigFile
(
config
,
"MultiScale"
,
""
,
(
*
this
));
// if (action_manager) action_manager->init();
// if (filter) filter->init();
Communicator
::
getGroup
(
"all"
).
synchronize
();
#ifdef LIBMULTISCALE_USE_EPSN
UInt
epsn_status
=
0
;
// EPSN Ready
DUMP
(
"EPSN is going to be READY..."
);
epsn_status
=
epsn_itfc
->
ready
();
if
(
!
epsn_status
)
{
FATAL
(
"error on EPSN Node ready operation
\n
"
);
}
DUMP
(
"EPSN READY"
);
// the main loop
DUMP
(
"EPSN Begin HTG"
);
epsn_itfc
->
beginHTM
();
epsn_itfc
->
beginLoop
(
"main"
);
DUMP
(
"simulation ready to start for EPSN"
);
#endif
return
Dim
;
}
/* -------------------------------------------------------------------------- */
#define BOOST_PARSE_MODEL(keyword, class, dim) \
DUMPFILE(Parser::fout, "trying to create class " \
<< stringify_macro(class) \
<< " while dimension is " << Dim << " dim is " \
<< dim << " key is " << key << " keyword is " \
<< keyword); \
if (key == keyword && dim == Dim) { \
if (Communicator::getCommunicator().getNbGroups() == 0) \
LM_FATAL("PROCESSOR KEYWORD SHOULD BE USED ON ID " << ID); \
auto &dom_group = Communicator::getCommunicator().getGroup(ID); \
model = std::make_shared<class>(ID, dom_group); \
Parser::parseConfigFile(config_file, keyword, ID, *model); \
DUMP("Loading of config file ... done", DBG_INFO_STARTUP); \
if (model == NULL) \
LM_FATAL("Could not instanciate the model: " \
<< " conf line was " << line.str()); \
model->checkAllKeywordsAreParsed(); \
model->init(); \
addObject(model); \
DUMPFILE(Parser::fout, \
"creation of " << stringify_macro(class) << " successful"); \
\
return true; \
}
#define BOOST_PARSE_MODEL_KEY(n, data, class) \
BOOST_PARSE_MODEL(stringify_macro(BOOST_PP_TUPLE_ELEM(3, 2, class)), \
BOOST_PP_TUPLE_ELEM(3, 0, class), \
BOOST_PP_TUPLE_ELEM(3, 1, class))
/* -------------------------------------------------------------------------- */
UInt
DomainMultiScale
::
parseLineModel
(
std
::
stringstream
&
line
)
{
// first of all check if the communicator is already set correctly
try
{
Communicator
&
myComm
__attribute__
((
unused
))
=
Communicator
::
getCommunicator
();
}
catch
(
LibMultiScaleException
&
e
)
{
if
(
lm_world_size
==
1
)
Communicator
::
createCommunicator
();
else
LM_THROW
(
"Communicator was not set: "
<<
" before MODEL keyword the COM keyword should have been used"
);
}
std
::
string
key
,
config_file
;
std
::
shared_ptr
<
DomainInterface
>
model
;
LMID
ID
=
invalidDomain
;
// parse the keyword of the model
Parser
::
parse
(
key
,
line
);
// parse the ID of the model
Parser
::
parse
(
ID
,
line
);
// parse the config file of the model
try
{
Parser
::
parse
(
config_file
,
line
);
}
catch
(
LibMultiScaleException
&
e
)
{
config_file
=
Parser
::
getCurrentConfigFile
();
}
BOOST_PP_SEQ_FOR_EACH
(
BOOST_PARSE_MODEL_KEY
,
f
,
LIST_ATOM_MODEL
)
BOOST_PP_SEQ_FOR_EACH
(
BOOST_PARSE_MODEL_KEY
,
f
,
LIST_CONTINUUM_MODEL
)
BOOST_PP_SEQ_FOR_EACH
(
BOOST_PARSE_MODEL_KEY
,
f
,
LIST_DD_MODEL
)
LM_FATAL
(
"Unknown Model type "
<<
key
<<
" maybe you should compile support "
"for this plugin ? or check the "
"dimension required ?"
);
return
false
;
}
/* -------------------------------------------------------------------------- */
/* LMDESC MultiScale Section (toplevel domain)
This section describe the most general keyword that
can be used. It allows to specify general values
of the simulation to be run.
*/
/* LMSYNTAX TODO */
/* LMEXAMPLE TODO */
ParseResult
DomainMultiScale
::
setParam
(
const
std
::
string
&
key
,
std
::
stringstream
&
line
)
{
if
(
key
==
"MD_CODE"
or
key
==
"ELAST_CODE"
or
key
==
"DD_CODE"
)
return
parseLineModel
(
line
);
/* LMKEYWORD MODEL String Integer config_file(current_file)
Declare a new domain to be created based on the
plugins compiled. Up to now the possible models are:
- LAMMPS
- MD1D
- MECA1D
- AKANTU
- PARADIS
*/
else
if
(
key
==
"MODEL"
)
return
parseLineModel
(
line
);
/* LMKEYWORD COUPLING_CODE ARG
TODO
*/
else
if
(
key
==
"COUPLING_CODE"
)
{
return
CouplerManager
::
getManager
().
parseCouplingLine
(
line
,
Dim
);
}
/* LMKEYWORD GEOMETRY ARG
TODO
*/
else
if
(
key
==
"GEOMETRY"
)
{
if
(
!
GeometryManager
::
allocated
())
LM_FATAL
(
"Please use DIMENSION keyword before"
<<
Parser
::
getParserState
());
return
GeometryManager
::
getManager
().
parseLine
(
line
,
Dim
);
}
/* LMKEYWORD DIMENSION Integer
TODO
*/
else
if
(
key
==
"DIMENSION"
)
{
Parser
::
parse
((
UInt
&
)
Dim
,
line
);
spatial_dimension
=
Dim
;
DUMP
(
"parsing DIMENSION commande = "
<<
Dim
,
DBG_INFO_STARTUP
);
ActionManager
::
getManager
();
FilterManager
::
getManager
();
CouplerManager
::
getManager
();
GeometryManager
::
getManager
();
return
true
;
}
/* LMKEYWORD DUMPER String
TODO
\ref{dumpersSection}
*/
else
if
(
key
==
"DUMPER"
)
{
if
(
!
ActionManager
::
allocated
())
LM_FATAL
(
"Please use DIMENSION keyword before"
<<
Parser
::
getParserState
());
return
ActionManager
::
getManager
().
parseActionLine
(
line
,
at_dumper
);
}
/* LMKEYWORD FILTER String
TODO
\ref{filterSection}
*/
else
if
(
key
==
"FILTER"
)
{
if
(
!
FilterManager
::
allocated
())
LM_FATAL
(
"Please use DIMENSION keyword before"
<<
Parser
::
getParserState
());
return
FilterManager
::
getManager
().
parseActionLine
(
line
,
at_filter
);
}
else
if
(
key
==
"COMPUTE"
)
{
if
(
!
FilterManager
::
allocated
())
LM_FATAL
(
"Please use DIMENSION keyword before"
<<
Parser
::
getParserState
());
return
FilterManager
::
getManager
().
parseActionLine
(
line
,
at_compute
);
}
/* LMKEYWORD STIMULATION String
TODO
\ref{stimulatorsSection}
*/
else
if
(
key
==
"STIMULATION"
)
{
if
(
!
ActionManager
::
allocated
())
LM_FATAL
(
"Please use DIMENSION keyword before"
<<
Parser
::
getParserState
());
return
ActionManager
::
getManager
().
parseActionLine
(
line
,
at_stimulator
);
}
/* LMKEYWORD UNITCODE String
TODO
*/
else
if
(
key
==
"UNITCODE"
)
{
DUMP
(
"parsing UNITCODE commande = "
<<
line
.
str
(),
DBG_INFO_STARTUP
);
Parser
::
parse
(
code_unit_system
,
line
);
Parser
::
units_converter
.
setOutUnits
(
code_unit_system
);
Parser
::
units_converter
.
computeConversions
();
if
(
lm_my_proc_id
==
0
)
code_unit_system
.
print
();
return
true
;
}
/* LMKEYWORD PROCESSORS Integer Integer
TODO
*/
else
if
(
key
==
"PROCESSORS"
)
{
LMID
id
;
Parser
::
parse
(
id
,
line
);
UInt
nb_procs
=
0
;
Parser
::
parse
(
nb_procs
,
line
);
if
(
nb_procs
==
0
)
LM_FATAL
(
"a group cannot be constituted of zero processors"
);
DUMPFILE
(
Parser
::
fout
,
"parsing "
<<
key
<<
"( Integer , Integer ) with value "
<<
id
<<
" "
<<
nb_procs
);
try
{
Communicator
::
getCommunicator
().
addGroup
(
id
,
nb_procs
);
}
catch
(
LibMultiScaleException
&
e
)
{
LM_FATAL_RE
(
e
,
"COM keyword should be used before the PROCESSOR keyword"
);
}
return
true
;
}
/* LMKEYWORD COM String
TODO
*/
else
if
(
key
==
"COM"
)
{
std
::
string
mot
;
Parser
::
parse
(
mot
,
line
);
Communicator
::
createCommunicator
();
return
true
;
}
// /* LMKEYWORD GLOBAL_TIMESTEP Time
// TODO
// */
// else if (key == "GLOBAL_TIMESTEP") {
// Real dt;
// Parser::parse(dt, line);
// this->setTimeStep(dt);
// DUMPBYPROC("changing global timestep to " << dt, DBG_MESSAGE, 0);
// return true;
// }
// /* LMKEYWORD SET_CURRENT_STEP Integer
// TODO
// */
// else if (key == "SET_CURRENT_STEP") {
// UInt ts;
// Parser::parse(ts, line);
// this->setCurrentStep(ts);
// DUMPBYPROC("changing current timestep to " << ts, DBG_MESSAGE, 0);
// return true;
// }
/* LMKEYWORD RESTART_FILE String
TODO
*/
else
if
(
key
==
"RESTART_FILE"
)
{
LMID
domainID
;
Parser
::
parse
(
domainID
,
line
);
std
::
string
mot
;
Parser
::
parse
(
mot
,
line
);
DUMP
(
"reloading file "
<<
mot
<<
" for domain "
<<
domainID
,
DBG_MESSAGE
);
if
(
getSharedObject
(
domainID
))
{
if
(
Communicator
::
getGroup
(
domainID
).
amIinGroup
())
getSharedObject
(
domainID
)
->
readXMLFile
(
mot
);
}
else
LM_FATAL
(
"there is no domain with ID "
<<
domainID
);
return
true
;
}
Communicator
::
getGroup
(
"all"
).
synchronize
();
return
false
;
}
/* -------------------------------------------------------------------------- */
std
::
shared_ptr
<
DomainInterface
>
DomainMultiScale
::
getModelByNumber
(
UInt
i
)
{
auto
iest_domain
=
std
::
next
(
insert_order
.
begin
(),
i
);
return
shared_pointer_objects
[
*
iest_domain
];
}
/* -------------------------------------------------------------------------- */
UInt
DomainMultiScale
::
getNbModels
()
{
return
objects
.
size
();
}
/* -------------------------------------------------------------------------- */
#define DOMAINLOOP(inloop) \
\
for (auto &obj : objects) { \
if (Communicator::getGroup(obj.first).amIinGroup()) \
inloop; \
}
#define DEFINE_RETURN_REAL_FUNCTION_BYSUM(name) \
Real DomainMultiScale::name() { \
Real res = 0; \
DOMAINLOOP(res += obj.second->name()) \
return res; \
}
/* -------------------------------------------------------------------------- */
Component
&
getRegisteredComponent
(
const
std
::
string
&
component_name
)
{
auto
managers
=
std
::
forward_as_tuple
(
DomainMultiScale
::
getManager
(),
FilterManager
::
getManager
(),
CouplerManager
::
getManager
(),
ActionManager
::
getManager
());
Component
*
ptr
=
nullptr
;
int
found
=
0
;
auto
find_comp
=
[
&
](
auto
&
manager
)
{
try
{
auto
&
component
=
manager
.
getObject
(
component_name
);
ptr
=
&
component
;
++
found
;
}
catch
(
UnknownID
&
e
)
{
}
};
std
::
apply
([
&
](
auto
&&
...
manager
)
{
(
find_comp
(
manager
),
...);
},
managers
);
if
(
found
>
1
)
{
LM_FATAL
(
"several components are registered with the name: "
<<
component_name
<<
" "
<<
ptr
);
}
if
(
not
ptr
)
{
LM_THROW
(
"component "
<<
component_name
<<
" cannot be found"
<<
std
::
endl
);
}
return
*
ptr
;
}
/* -------------------------------------------------------------------------- */
OutputContainer
getRegisteredOutput
(
const
std
::
string
&
name
)
{
std
::
string
component_name
=
name
;
std
::
string
output_name
=
""
;
auto
pos
=
component_name
.
find
(
"."
);
if
(
pos
!=
std
::
string
::
npos
)
{
output_name
=
component_name
.
substr
(
pos
+
1
);
component_name
=
component_name
.
substr
(
0
,
pos
);
}
auto
&
comp
=
getRegisteredComponent
(
component_name
);
if
(
output_name
!=
""
)
return
comp
.
evalOutput
(
output_name
);
OutputContainer
out
;
out
=
comp
;
return
out
;
}
/* -------------------------------------------------------------------------- */
template
<>
std
::
unique_ptr
<
IDManager
<
DomainInterface
>>
IDManager
<
DomainInterface
>::
static_pointer
=
NULL
;
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
Event Timeline
Log In to Comment