PLaSK library
Loading...
Searching...
No Matches
solver.hpp
Go to the documentation of this file.
1
/*
2
* This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3
* Copyright (c) 2022 Lodz University of Technology
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, version 3.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*/
14
#ifndef PLASK__SOLVER_H
15
#define PLASK__SOLVER_H
16
507
#include <string>
508
509
#include "
log/log.hpp
"
510
#include "
log/data.hpp
"
511
#include "
mesh/mesh.hpp
"
512
#include "
geometry/space.hpp
"
513
#include "
geometry/reader.hpp
"
514
#include "
manager.hpp
"
515
516
namespace
plask
{
517
518
struct
Manager;
519
525
class
PLASK_API
Solver
{
526
528
std::string solver_name;
529
530
protected
:
531
533
bool
initialized
;
534
540
virtual
void
onInitialize
() {}
541
548
virtual
void
onInvalidate
() {}
549
550
public
:
551
557
bool
initCalculation();
558
563
Solver
(
const
std::string& name=
""
): solver_name(name), initialized(
false
) {}
564
566
virtual
~Solver
() {}
567
577
virtual
void
loadConfiguration(
XMLReader
& source,
Manager
& manager);
578
589
void
parseStandardConfiguration(
XMLReader
& source,
Manager
& manager,
const
std::string&
expected_msg
=
"solver configuration element"
);
590
595
bool
isInitialized
() {
return
initialized; }
596
603
void
invalidate
() {
604
if
(initialized) {
605
initialized =
false
;
606
writelog
(
LOG_INFO
,
"Invalidating solver"
);
607
onInvalidate();
608
}
609
}
610
615
virtual
std::string
getClassName
()
const
= 0;
616
621
inline
std::string
getId
()
const
{
622
std::string name =
""
;
623
if
(solver_name !=
""
) {
624
name += solver_name; name +=
":"
;
625
}
626
return
name + getClassName();
627
}
628
630
inline
std::string
getName
()
const
{
return
solver_name; }
631
636
virtual
std::string
getClassDescription
()
const
{
return
""
; }
637
638
template
<
typename
ArgT =
double
,
typename
ValT =
double
>
639
DataLog<ArgT, ValT>
dataLog
(
const
std::string& chart_name,
const
std::string& axis_arg_name,
const
std::string& axis_val_name) {
640
return
DataLog<ArgT, ValT>
(getId(), chart_name, axis_arg_name, axis_val_name);
641
}
642
643
644
template
<
typename
ArgT =
double
,
typename
ValT =
double
>
645
DataLog<ArgT, ValT>
dataLog
(
const
std::string& axis_arg_name,
const
std::string& axis_val_name) {
646
return
DataLog<ArgT, ValT>
(getId(), axis_arg_name, axis_val_name);
647
}
648
655
template
<
typename
...Args>
656
void
writelog
(
LogLevel
level, std::string
msg
,
Args
&&... params)
const
{
plask::writelog
(level, getId() +
": "
+
msg
, std::forward<Args>(params)...); }
657
658
//virtual shared_ptr<const Geometry> getUsedGeometry() const; //return empty by default
659
//virtual shared_ptr<const Mesh> getUsedMesh() const;
660
661
};
662
663
/*
664
* Function constructing solver on library loadConfiguration
665
*/
666
#define SOLVER_CONSTRUCT_FUNCTION_SUFFIX "_solver_factory"
667
extern
"C"
typedef
Solver
*
solver_construct_f
(
const
std::string& name);
668
669
670
template
<
typename
,
typename
>
struct
SolverWithMesh
;
671
675
template
<
typename
SpaceT>
676
class
SolverOver
:
public
Solver
{
677
678
void
diconnectGeometry() {
679
if
(this->
geometry
)
680
this->
geometry
->changedDisconnectMethod(
this
, &
SolverOver<SpaceT>::onGeometryChange
);
681
}
682
683
protected
:
684
686
shared_ptr<SpaceT>
geometry
;
687
694
template
<
typename
Boundary,
typename
ConditionT>
695
void
readBoundaryConditions
(
Manager
& manager,
XMLReader
& reader,
BoundaryConditions<Boundary, ConditionT>
&
dest
) {
696
manager.
readBoundaryConditions
<
Boundary
,
ConditionT
>(reader,
dest
);
697
}
698
699
public
:
700
702
typedef
SpaceT
SpaceType
;
703
704
SolverOver
(
const
std::string& name=
""
) :
Solver
(name) {}
705
706
~SolverOver
() {
707
diconnectGeometry();
708
}
709
710
void
loadConfiguration
(
XMLReader
& source,
Manager
& manager)
override
;
711
712
void
parseStandardConfiguration
(
XMLReader
& source,
Manager
& manager,
const
std::string&
expected_msg
=
"solver configuration element"
);
713
719
virtual
void
onGeometryChange
(
const
Geometry::Event
&) {
720
this->
invalidate
();
721
}
722
727
inline
shared_ptr<SpaceT>
getGeometry
()
const
{
return
geometry
; }
728
733
void
setGeometry
(
const
shared_ptr<SpaceT>&
geometry
) {
734
if
(
geometry
== this->geometry)
return
;
735
writelog
(
LOG_INFO
,
"Attaching geometry to solver"
);
736
diconnectGeometry();
737
this->geometry =
geometry
;
738
if
(this->geometry)
739
this->geometry->changedConnectMethod(
this
, &
SolverOver<SpaceT>::onGeometryChange
);
740
onGeometryChange
(
Geometry::Event
(
geometry
.get(), 0));
741
}
742
};
743
747
template
<
typename
SpaceT,
typename
MeshT>
748
struct
SolverWithMesh
:
public
SolverOver
<SpaceT> {
749
751
typedef
MeshT
MeshType
;
752
753
private
:
754
755
shared_ptr<MeshGeneratorD<MeshT::DIM>
> mesh_generator;
756
757
void
disconnectMesh() {
758
/*if (this->mesh)
759
this->mesh->changedDisconnectMethod(this, &SolverWithMesh<SpaceT, MeshT>::onMeshChange);*/
760
mesh_signal_connection
.disconnect();
761
}
762
763
void
clearGenerator() {
764
if
(this->mesh_generator)
765
this->mesh_generator->changedDisconnectMethod(
this
, &
SolverWithMesh<SpaceT, MeshT>::onGeneratorChange
);
766
mesh_generator.reset();
767
}
768
769
void
regenerateMesh() {
770
if
(this->mesh_generator && this->
geometry
) {
771
auto
mesh
= mesh_generator->template
get<MeshType>
(this->
geometry
->getChild());
772
if
(
mesh
== this->
mesh
)
return
;
773
disconnectMesh();
774
this->
mesh
=
mesh
;
775
if
(this->
mesh
)
776
mesh_signal_connection
= this->
mesh
->changedConnectMethod(
this
, &
SolverWithMesh<SpaceT, MeshT>::onMeshChange
);
777
onMeshChange
(
typename
MeshT::Event(
mesh
.get(), 0));
778
}
779
}
780
785
void
onGeneratorChange(
const
typename
MeshGenerator::Event
&) {
786
regenerateMesh();
787
}
788
789
protected
:
790
792
shared_ptr<MeshT>
mesh
;
793
795
boost::signals2::connection
mesh_signal_connection
;
796
797
public
:
798
799
SolverWithMesh
(
const
std::string& name=
""
) :
SolverOver
<
SpaceT
>(name) {}
800
801
~SolverWithMesh
() {
802
disconnectMesh();
803
clearGenerator();
804
}
805
806
void
loadConfiguration
(
XMLReader
& source,
Manager
& manager)
override
;
807
808
void
parseStandardConfiguration
(
XMLReader
& source,
Manager
& manager,
const
std::string&
expected_msg
=
"solver configuration element"
);
809
815
virtual
void
onMeshChange
(
const
typename
MeshT::Event&
PLASK_UNUSED
(
evt
)) {
816
this->
invalidate
();
817
}
818
826
void
onGeometryChange
(
const
Geometry::Event
&
PLASK_UNUSED
(
evt
))
override
{
827
this->
invalidate
();
828
this->regenerateMesh();
829
}
830
837
inline
MeshT
&
meshRef
()
const
{
return
*
mesh
; }
838
843
inline
shared_ptr<MeshT>
getMesh
()
const
{
return
mesh
; }
844
849
void
setMesh
(
const
shared_ptr<MeshT>&
mesh
) {
850
clearGenerator();
851
if
(
mesh
== this->mesh)
return
;
852
this->
writelog
(
LOG_INFO
,
"Attaching mesh to solver"
);
853
disconnectMesh();
854
this->mesh =
mesh
;
855
if
(this->mesh)
856
mesh_signal_connection
= this->mesh->changedConnectMethod(
this
, &
SolverWithMesh<SpaceT, MeshT>::onMeshChange
);
857
onMeshChange
(
typename
MeshT::Event(
mesh
.get(), 0));
858
}
859
864
void
setMesh
(shared_ptr<
MeshGeneratorD<MeshT::DIM>
> generator) {
865
clearGenerator();
866
this->
writelog
(
LOG_INFO
,
"Attaching mesh generator to solver"
);
867
mesh_generator = generator;
868
if
(mesh_generator)
869
mesh_generator->changedConnectMethod(
this
, &
SolverWithMesh<SpaceT, MeshT>::onGeneratorChange
);
870
regenerateMesh();
871
}
872
};
873
874
}
//namespace plask
875
876
#include "
manager.hpp
"
// Just in case module author includes only "solver.hpp"
877
878
namespace
plask
{
879
880
template
<
typename
SpaceT>
881
void
SolverOver<SpaceT>::loadConfiguration
(
XMLReader
& reader,
Manager
& manager) {
882
while
(reader.
requireTagOrEnd
()) parseStandardConfiguration(reader, manager,
"<geometry>"
);
883
}
884
885
template
<
typename
SpaceT,
typename
MeshT>
886
void
SolverWithMesh<SpaceT, MeshT>::loadConfiguration
(
XMLReader
& reader,
Manager
& manager) {
887
while
(reader.
requireTagOrEnd
()) parseStandardConfiguration(reader, manager,
"<geometry> or <mesh>"
);
888
}
889
890
891
template
<
typename
SpaceT>
892
void
SolverOver<SpaceT>::parseStandardConfiguration
(
XMLReader
& reader,
Manager
& manager,
const
std::string&
expected_msg
) {
893
if
(reader.
getNodeName
() ==
"geometry"
) {
894
auto
name = reader.
getAttribute
(
"ref"
);
895
if
(!name) name.reset(reader.
requireTextInCurrentTag
());
896
else
reader.
requireTagEnd
();
897
auto
found
= manager.
geometrics
.find(*name);
898
if
(
found
== manager.
geometrics
.end())
899
throw
BadInput
(this->getId(),
"geometry '{0}' not found"
, *name);
900
else
{
901
auto
geometry =
dynamic_pointer_cast<SpaceT>
(
found
->second);
902
if
(!geometry)
throw
BadInput
(this->getId(),
"geometry '{0}' of wrong type"
, *name);
903
this->setGeometry(geometry);
904
}
905
}
else
{
906
Solver::parseStandardConfiguration
(reader, manager,
expected_msg
);
907
}
908
}
909
910
template
<
typename
SpaceT,
typename
MeshT>
911
void
SolverWithMesh<SpaceT, MeshT>::parseStandardConfiguration
(
XMLReader
& reader,
Manager
& manager,
const
std::string&
expected_msg
) {
912
if
(reader.
getNodeName
() ==
"mesh"
) {
913
auto
name = reader.
getAttribute
(
"ref"
);
914
if
(!name) name.reset(reader.
requireTextInCurrentTag
());
915
else
reader.
requireTagEnd
();
916
auto
found
= manager.
meshes
.find(*name);
917
if
(
found
!= manager.
meshes
.end()) {
918
if
(shared_ptr<MeshT> mesh =
dynamic_pointer_cast<MeshT>
(
found
->second)) {
919
this->setMesh(mesh);
920
}
else
{
921
auto
generator =
dynamic_pointer_cast<MeshGeneratorD<MeshT::DIM>
>(
found
->second);
922
if
(!generator)
throw
BadInput
(this->getId(),
"mesh or generator '{0}' of wrong type"
, *name);
923
this->setMesh(generator);
924
}
925
}
926
}
else
{
927
SolverOver<SpaceT>::parseStandardConfiguration
(reader, manager,
expected_msg
);
928
}
929
}
930
931
}
// namespace plask
932
933
#endif
// PLASK__SOLVER_H
plask
solver.hpp
Generated by
1.9.8