Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F68899227
component_libmultiscale_inline_impl.hh
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, Jun 29, 09:45
Size
9 KB
Mime Type
text/x-c++
Expires
Mon, Jul 1, 09:45 (19 h, 41 m)
Engine
blob
Format
Raw Data
Handle
18645088
Attached To
rLIBMULTISCALE LibMultiScale
component_libmultiscale_inline_impl.hh
View Options
/**
* @file component_libmultiscale.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This describe the root objects to be combined into valid LM
* components
*
* @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/>.
*
*/
#ifndef __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_INLINE_IMPL_HH__
#define __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_INLINE_IMPL_HH__
/* -------------------------------------------------------------------------- */
#include "auto_arguments.hh"
#include "component_libmultiscale.hh"
#include "container_array.hh"
#include "lm_common.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
class
Component
;
/* -------------------------------------------------------------------------- */
using
dispatch
=
AutoDispatch
::
dispatch
;
template
<
typename
T
,
typename
...
Ts
>
using
enable_if_type
=
AutoDispatch
::
enable_if_type
<
T
,
Ts
...
>
;
/* --------------------------------------------------------------------- */
// OutputContainer
/* --------------------------------------------------------------------- */
template
<
typename
T
>
inline
OutputContainer
&
OutputContainer
::
operator
=
(
T
&&
v
)
{
AutoDispatch
::
ArgumentAny
::
operator
=
(
std
::
forward
<
T
>
(
v
));
return
*
this
;
}
template
<
typename
type
,
typename
...
T
>
decltype
(
auto
)
OutputContainer
::
alloc
(
T
&&
...
construction_parameters
)
{
try
{
this
->
get
<
type
>
();
}
catch
(
AutoDispatch
::
no_argument
&
e
)
{
(
*
this
)
=
type
(
construction_parameters
...);
}
auto
&
output
=
this
->
get
<
type
>
();
if
(
component
)
output
.
acquireContext
(
*
component
);
return
output
;
}
/* --------------------------------------------------------------------- */
// InputContainer
/* --------------------------------------------------------------------- */
template
<
typename
T
>
inline
InputContainer
&
InputContainer
::
operator
=
(
T
&&
v
)
{
auto
out
=
std
::
make_shared
<
OutputContainer
>
();
*
out
=
std
::
forward
<
T
>
(
v
);
output_reference
=
out
;
return
*
this
;
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
decltype
(
auto
)
InputContainer
::
get
()
{
OutputContainer
&
out
=
this
->
get
();
return
out
.
get
<
T
>
();
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
decltype
(
auto
)
InputContainer
::
get
()
const
{
OutputContainer
&
out
=
this
->
get
();
return
out
.
get
<
T
>
();
}
/* -------------------------------------------------------------------------- */
// Component
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
void
Component
::
setCommGroup
(
CommGroup
&
group
)
{
LMObject
::
setCommGroup
(
group
);
for
(
auto
&&
[
key
,
output
]
:
this
->
outputs
)
{
try
{
this
->
getOutputAsArray
<
T
>
(
key
).
setCommGroup
(
group
);
}
catch
(
AutoDispatch
::
no_argument
&
e
)
{
// do nothing: cannot clean unallocated pointer
}
catch
(
AutoDispatch
::
bad_argument_cast
&
e
)
{
// do nothing: it is not an array
}
catch
(
std
::
bad_cast
&
e
)
{
// do nothing: it is not an array
}
}
}
/* --------------------------------------------------------------------- */
template
<
typename
ContMap
>
inline
decltype
(
auto
)
Component
::
getContainer
(
const
std
::
string
&
required_name
,
ContMap
&
cont
)
{
std
::
string
container_type
=
"unknown"
;
if
constexpr
(
std
::
is_same_v
<
ContMap
,
decltype
(
this
->
inputs
)
>
)
container_type
=
"input"
;
else
if
constexpr
(
std
::
is_same_v
<
ContMap
,
decltype
(
this
->
outputs
)
>
)
container_type
=
"output"
;
std
::
string
name
=
required_name
;
if
(
name
==
""
)
{
if
constexpr
(
std
::
is_same_v
<
ContMap
,
decltype
(
this
->
outputs
)
>
)
name
=
this
->
default_output
;
}
if
(
name
==
""
)
{
if
(
cont
.
size
()
==
0
)
{
LM_FATAL
(
"There is no "
<<
container_type
<<
" for "
<<
this
->
getID
());
}
else
if
(
cont
.
size
()
!=
1
)
{
std
::
string
mesg
=
this
->
getID
()
+
" "
+
container_type
+
" has several entries: need a name"
;
mesg
+=
"
\n\n
Possible names:
\n\n
"
;
for
(
auto
&&
pair
:
cont
)
{
mesg
+=
"
\t
"
+
pair
.
first
+
"
\n
"
;
}
LM_FATAL
(
mesg
);
}
name
=
cont
.
begin
()
->
first
;
}
else
{
auto
search
=
cont
.
find
(
name
);
if
(
search
==
cont
.
end
())
{
std
::
string
mesg
=
this
->
getID
()
+
":"
+
name
+
": "
+
container_type
+
" not existing"
;
mesg
+=
"
\n\n
Possibilities are:
\n\n
"
;
for
(
auto
&&
pair
:
cont
)
{
mesg
+=
"
\t
"
+
pair
.
first
+
"
\n
"
;
}
LM_FATAL
(
mesg
);
}
}
return
std
::
forward_as_tuple
(
name
,
cont
[
name
]);
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
inline
decltype
(
auto
)
Component
::
getOutput
(
const
std
::
string
&
output_name
)
{
return
getOutput
(
output_name
).
get
<
T
>
();
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
inline
decltype
(
auto
)
Component
::
evalOutput
(
const
std
::
string
&
output_name
)
{
this
->
compute
();
return
getOutput
<
T
>
(
output_name
);
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
inline
decltype
(
auto
)
Component
::
evalArrayOutput
(
const
std
::
string
&
output_name
)
{
return
evalOutput
(
output_name
).
get
<
ContainerArray
<
T
>>
();
}
/* --------------------------------------------------------------------- */
template
<
typename
Cont
,
typename
...
T
>
auto
&
Component
::
allocOutput
(
const
std
::
string
&
output_name
,
T
&&
...
construction_parameters
)
{
using
type
=
typename
Cont
::
ContainerSubset
;
try
{
this
->
getOutput
(
output_name
).
get
<
type
>
();
}
catch
(
AutoDispatch
::
no_argument
&
e
)
{
this
->
getOutput
(
output_name
).
alloc
<
type
>
(
construction_parameters
...);
}
auto
&
output
=
getOutput
(
output_name
).
get
<
type
>
();
return
output
;
}
/* --------------------------------------------------------------------- */
template
<
typename
Names
>
void
Component
::
createArrayOutputs
(
Names
&&
output_names
)
{
for
(
auto
&&
f
:
output_names
)
{
this
->
createArrayOutput
(
f
);
}
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
void
Component
::
createArrayOutput
(
const
std
::
string
&
name
)
{
this
->
createOutput
(
name
);
this
->
getOutput
(
name
)
=
ContainerArray
<
T
>
(
this
->
getID
()
+
":"
+
name
);
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
ContainerArray
<
T
>
&
Component
::
getOutputAsArray
(
const
std
::
string
&
output_name
)
{
return
this
->
getOutput
(
output_name
).
get
<
ContainerArray
<
T
>>
();
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
void
Component
::
connect
(
const
std
::
string
&
input
,
T
&&
arg
)
{
auto
search
=
inputs
.
find
(
input
);
if
(
search
==
inputs
.
end
())
{
DUMP
(
input
+
": input not existing"
,
DBG_MESSAGE
);
if
(
inputs
.
size
()
>
0
)
{
DUMP
(
"Possible inputs are:"
,
DBG_MESSAGE
);
for
(
auto
p
:
inputs
)
{
DUMP
(
"
\t
"
+
p
.
first
+
"
\n
"
,
DBG_MESSAGE
);
}
}
else
{
DUMP
(
"there are no possible inputs"
,
DBG_MESSAGE
);
}
LM_FATAL
(
"abort:"
+
input
+
": input not existing"
);
}
inputs
[
input
]
=
std
::
forward
<
T
>
(
arg
);
}
/* --------------------------------------------------------------------- */
template
<
typename
T
,
typename
...
Ts
>
inline
std
::
enable_if_t
<
std
::
is_same_v
<
std
::
decay_t
<
T
>
,
InputConnection
>>
Component
::
compute
(
T
&&
arg
,
Ts
&&
...
args
)
{
auto
tup_args
=
std
::
forward_as_tuple
(
arg
,
args
...);
apply
(
[
&
](
auto
&&
...
_arg
)
{
(
this
->
connect
(
_arg
.
name
,
std
::
forward
<
OutputContainer
>
(
_arg
.
val
)),
...);
},
tup_args
);
this
->
compute
();
}
/* --------------------------------------------------------------------- */
template
<
typename
T
>
inline
std
::
enable_if_t
<
not
std
::
is_same_v
<
std
::
decay_t
<
T
>
,
InputConnection
>>
Component
::
compute
(
T
&&
arg
)
{
// get the default input
auto
&&
[
input
,
arg_cont_input
]
=
getContainer
(
""
,
inputs
);
arg_cont_input
=
std
::
forward
<
T
>
(
arg
);
this
->
compute
();
}
/* --------------------------------------------------------------------- */
// array output management
/* --------------------------------------------------------------------- */
template
<
typename
F
>
void
Component
::
applyArrayOutput
(
F
&&
f
,
const
std
::
string
&
name
)
{
try
{
auto
&
_output
=
this
->
getOutputAsArray
(
name
);
f
(
_output
);
}
catch
(
AutoDispatch
::
no_argument
&
e
)
{
// do nothing: cannot clean unallocated pointer
}
catch
(
AutoDispatch
::
bad_argument_cast
&
e
)
{
// do nothing: it is not an array
}
catch
(
std
::
bad_cast
&
e
)
{
// do nothing: it is not an array
}
}
/* --------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif
/* __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_INLINE_IMPL_HH__ */
Event Timeline
Log In to Comment