Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91663808
ExtrinsicModelDriftDiffusion.cpp
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
Wed, Nov 13, 05:56
Size
23 KB
Mime Type
text/x-c
Expires
Fri, Nov 15, 05:56 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
22303334
Attached To
rLAMMPS lammps
ExtrinsicModelDriftDiffusion.cpp
View Options
// ATC Headers
#include "ExtrinsicModelDriftDiffusion.h"
#include "ATC_Error.h"
#include "FieldEulerIntegrator.h"
#include "ATC_Coupling.h"
#include "LammpsInterface.h"
#include "PrescribedDataManager.h"
#include "PhysicsModel.h"
#include "LinearSolver.h"
#include "PoissonSolver.h"
#include "SchrodingerSolver.h"
// timer
#include "Utility.h"
#include <utility>
using
ATC_Utility
::
to_string
;
using
std
::
cout
;
using
std
::
string
;
using
std
::
set
;
using
std
::
pair
;
using
std
::
vector
;
namespace
ATC
{
//--------------------------------------------------------
//--------------------------------------------------------
// Class ExtrinsicModelDriftDiffusion
//--------------------------------------------------------
//--------------------------------------------------------
//--------------------------------------------------------
// Constructor
//--------------------------------------------------------
ExtrinsicModelDriftDiffusion
::
ExtrinsicModelDriftDiffusion
(
ExtrinsicModelManager
*
modelManager
,
ExtrinsicModelType
modelType
,
string
matFileName
)
:
ExtrinsicModelTwoTemperature
(
modelManager
,
modelType
,
matFileName
),
continuityIntegrator_
(
NULL
),
poissonSolverType_
(
DIRECT
),
// ITERATIVE | DIRECT
poissonSolver_
(
NULL
),
baseSize_
(
0
),
electronDensityEqn_
(
ELECTRON_CONTINUITY
),
fluxUpdateFreq_
(
1
),
schrodingerSolverType_
(
DIRECT
),
// ITERATIVE | DIRECT
schrodingerSolver_
(
NULL
),
schrodingerPoissonMgr_
(),
schrodingerPoissonSolver_
(
NULL
),
maxConsistencyIter_
(
0
),
maxConstraintIter_
(
1
),
safe_dEf_
(
0.1
),
Ef_shift_
(
0.0
),
oneD_
(
false
),
oneDcoor_
(
0
),
oneDconserve_
(
0
)
{
// delete base class's version of the physics model
if
(
physicsModel_
)
delete
physicsModel_
;
if
(
modelType
==
DRIFT_DIFFUSION_EQUILIBRIUM
)
{
physicsModel_
=
new
PhysicsModelDriftDiffusionEquilibrium
(
matFileName
);
electronDensityEqn_
=
ELECTRON_EQUILIBRIUM
;
}
else
if
(
modelType
==
DRIFT_DIFFUSION_SCHRODINGER
)
{
physicsModel_
=
new
PhysicsModelDriftDiffusionSchrodinger
(
matFileName
);
electronDensityEqn_
=
ELECTRON_SCHRODINGER
;
maxConsistencyIter_
=
1
;
}
else
if
(
modelType
==
DRIFT_DIFFUSION_SCHRODINGER_SLICE
)
{
physicsModel_
=
new
PhysicsModelDriftDiffusionSchrodingerSlice
(
matFileName
);
electronDensityEqn_
=
ELECTRON_SCHRODINGER
;
maxConsistencyIter_
=
1
;
}
else
{
physicsModel_
=
new
PhysicsModelDriftDiffusion
(
matFileName
);
}
atc_
->
useConsistentMassMatrix_
(
ELECTRON_DENSITY
)
=
true
;
rhsMaskIntrinsic_
(
ELECTRON_TEMPERATURE
,
SOURCE
)
=
true
;
//atc_->fieldMask_(ELECTRON_TEMPERATURE,EXTRINSIC_SOURCE) = true;
}
//--------------------------------------------------------
// Destructor
//--------------------------------------------------------
ExtrinsicModelDriftDiffusion
::~
ExtrinsicModelDriftDiffusion
()
{
if
(
continuityIntegrator_
)
delete
continuityIntegrator_
;
if
(
poissonSolver_
)
delete
poissonSolver_
;
if
(
schrodingerSolver_
)
delete
schrodingerSolver_
;
if
(
schrodingerPoissonSolver_
)
delete
schrodingerPoissonSolver_
;
}
//--------------------------------------------------------
// modify
//--------------------------------------------------------
bool
ExtrinsicModelDriftDiffusion
::
modify
(
int
narg
,
char
**
arg
)
{
bool
match
=
false
;
if
(
!
match
)
{
match
=
ExtrinsicModelTwoTemperature
::
modify
(
narg
,
arg
);
}
return
match
;
}
//--------------------------------------------------------
// initialize
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusion
::
initialize
()
{
// xTTM sets rhsMaskIntrinsic_
ExtrinsicModelTwoTemperature
::
initialize
();
nNodes_
=
atc_
->
num_nodes
();
rhs_
[
ELECTRON_DENSITY
].
reset
(
nNodes_
,
1
);
rhs_
[
ELECTRIC_POTENTIAL
].
reset
(
nNodes_
,
1
);
// set up electron continuity integrator
Array2D
<
bool
>
rhsMask
(
NUM_TOTAL_FIELDS
,
NUM_FLUX
);
rhsMask
=
false
;
for
(
int
i
=
0
;
i
<
NUM_FLUX
;
i
++
)
{
rhsMask
(
ELECTRON_DENSITY
,
i
)
=
atc_
->
fieldMask_
(
ELECTRON_DENSITY
,
i
);
}
// need to create the bcs for the solver to configure properly
atc_
->
set_fixed_nodes
();
if
(
continuityIntegrator_
)
delete
continuityIntegrator_
;
if
(
electronTimeIntegration_
==
TimeIntegrator
::
IMPLICIT
)
{
continuityIntegrator_
=
new
FieldImplicitEulerIntegrator
(
ELECTRON_DENSITY
,
physicsModel_
,
atc_
->
feEngine_
,
atc_
,
rhsMask
);
}
else
{
continuityIntegrator_
=
new
FieldExplicitEulerIntegrator
(
ELECTRON_DENSITY
,
physicsModel_
,
atc_
->
feEngine_
,
atc_
,
rhsMask
);
}
atc_
->
compute_mass_matrix
(
ELECTRON_DENSITY
,
physicsModel_
);
//(atc_->consistentMassMats_[ELECTRON_DENSITY].quantity()).print("PHYS MASS MAT");
//DENS_MAT temp = atc_->consistentMassInverse_ - atc_->consistentMassMatInv_[ELECTRON_DENSITY];
//temp.print("DIFF In MATS");
// set up poisson solver
rhsMask
=
false
;
for
(
int
i
=
0
;
i
<
NUM_FLUX
;
i
++
)
{
rhsMask
(
ELECTRIC_POTENTIAL
,
i
)
=
atc_
->
fieldMask_
(
ELECTRIC_POTENTIAL
,
i
);
}
int
type
=
ATC
::
LinearSolver
::
ITERATIVE_SOLVE_SYMMETRIC
;
if
(
poissonSolverType_
==
DIRECT
)
{
type
=
ATC
::
LinearSolver
::
DIRECT_SOLVE
;
}
if
(
poissonSolver_
)
delete
poissonSolver_
;
poissonSolver_
=
new
PoissonSolver
(
ELECTRIC_POTENTIAL
,
physicsModel_
,
atc_
->
feEngine_
,
atc_
->
prescribedDataMgr_
,
atc_
,
rhsMask
,
type
,
true
);
poissonSolver_
->
initialize
();
// set up schrodinger solver
if
(
electronDensityEqn_
==
ELECTRON_SCHRODINGER
)
{
if
(
schrodingerSolver_
)
delete
schrodingerSolver_
;
if
(
oneD_
)
{
EfHistory_
.
reset
(
oneDslices_
.
size
(),
2
);
schrodingerSolver_
=
new
SliceSchrodingerSolver
(
ELECTRON_DENSITY
,
physicsModel_
,
atc_
->
feEngine_
,
atc_
->
prescribedDataMgr_
,
atc_
,
oneDslices_
,
oneDdxs_
);
}
else
{
schrodingerSolver_
=
new
SchrodingerSolver
(
ELECTRON_DENSITY
,
physicsModel_
,
atc_
->
feEngine_
,
atc_
->
prescribedDataMgr_
,
atc_
);
}
schrodingerSolver_
->
initialize
();
if
(
schrodingerPoissonSolver_
)
delete
schrodingerPoissonSolver_
;
schrodingerPoissonSolver_
=
schrodingerPoissonMgr_
.
initialize
(
atc_
,
schrodingerSolver_
,
poissonSolver_
,
physicsModel_
);
}
if
(
electronDensityEqn_
==
ELECTRON_SCHRODINGER
&&
!
(
atc_
->
is_initialized
()))
{
((
atc_
->
fields
())[
ELECTRON_WAVEFUNCTION
].
set_quantity
()).
reset
(
nNodes_
,
1
);
((
atc_
->
fields
())[
ELECTRON_WAVEFUNCTIONS
].
set_quantity
()).
reset
(
nNodes_
,
nNodes_
);
((
atc_
->
fields
())[
ELECTRON_WAVEFUNCTION_ENERGIES
].
set_quantity
()).
reset
(
nNodes_
,
1
);
}
#if 0
cout << " RHS MASK\n";
print_mask(rhsMask);
#endif
}
//--------------------------------------------------------
// pre initial integration
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusion
::
pre_init_integrate
()
{
double
dt
=
atc_
->
lammpsInterface_
->
dt
();
double
time
=
atc_
->
time
();
int
step
=
atc_
->
step
();
if
(
step
%
fluxUpdateFreq_
!=
0
)
return
;
// set Dirchlet data
atc_
->
set_fixed_nodes
();
// set Neumann data (atc does not set these until post_final)
atc_
->
set_sources
();
// subcyle integration of fast electron variable/s
double
idt
=
dt
/
nsubcycle_
;
for
(
int
i
=
0
;
i
<
nsubcycle_
;
++
i
)
{
if
(
electronDensityEqn_
==
ELECTRON_CONTINUITY
)
{
// update continuity eqn
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRON_DENSITY
)
)
continuityIntegrator_
->
update
(
idt
,
time
,
atc_
->
fields_
,
rhs_
);
atc_
->
set_fixed_nodes
();
// solve poisson eqn for electric potential
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRIC_POTENTIAL
)
)
poissonSolver_
->
solve
(
atc_
->
fields
(),
rhs_
);
}
else
if
(
electronDensityEqn_
==
ELECTRON_SCHRODINGER
)
{
if
(
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRON_DENSITY
)
)
||
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRIC_POTENTIAL
)
)
)
schrodingerPoissonSolver_
->
solve
(
rhs_
,
fluxes_
);
}
// update electron temperature
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRON_TEMPERATURE
)
&&
temperatureIntegrator_
)
{
#ifdef ATC_VERBOSE
ATC
::
LammpsInterface
::
instance
()
->
stream_msg_once
(
"start temperature integration..."
,
true
,
false
);
#endif
temperatureIntegrator_
->
update
(
idt
,
time
,
atc_
->
fields_
,
rhs_
);
#ifdef ATC_VERBOSE
ATC
::
LammpsInterface
::
instance
()
->
stream_msg_once
(
" done"
,
false
,
true
);
#endif
}
atc_
->
set_fixed_nodes
();
}
}
//--------------------------------------------------------
// set coupling source terms
//-------------------------------------------------------
void
ExtrinsicModelDriftDiffusion
::
set_sources
(
FIELDS
&
fields
,
FIELDS
&
sources
)
{
atc_
->
evaluate_rhs_integral
(
rhsMaskIntrinsic_
,
fields
,
sources
,
atc_
->
source_integration
(),
physicsModel_
);
}
//--------------------------------------------------------
// output
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusion
::
output
(
OUTPUT_LIST
&
outputData
)
{
#ifdef ATC_VERBOSE
// ATC::LammpsInterface::instance()->print_msg_once("start output",true,false);
#endif
ExtrinsicModelTwoTemperature
::
output
(
outputData
);
// fields
outputData
[
"dot_electron_density"
]
=
&
(
atc_
->
dot_field
(
ELECTRON_DENSITY
)).
set_quantity
();
DENS_MAT
&
JE
=
rhs_
[
ELECTRON_TEMPERATURE
].
set_quantity
();
double
totalJouleHeating
=
JE
.
sum
();
outputData
[
"joule_heating"
]
=
&
JE
;
atc_
->
feEngine_
->
add_global
(
"total_joule_heating"
,
totalJouleHeating
);
Array2D
<
bool
>
rhsMask
(
NUM_FIELDS
,
NUM_FLUX
);
rhsMask
=
false
;
rhsMask
(
ELECTRON_DENSITY
,
FLUX
)
=
true
;
rhsMask
(
ELECTRIC_POTENTIAL
,
FLUX
)
=
true
;
atc_
->
compute_flux
(
rhsMask
,
atc_
->
fields_
,
fluxes_
,
physicsModel_
);
//(fluxes_[ELECTRON_DENSITY][0]).print("J_x");
outputData
[
"electron_flux_x"
]
=
&
fluxes_
[
ELECTRON_DENSITY
][
0
];
outputData
[
"electron_flux_y"
]
=
&
fluxes_
[
ELECTRON_DENSITY
][
1
];
outputData
[
"electron_flux_z"
]
=
&
fluxes_
[
ELECTRON_DENSITY
][
2
];
outputData
[
"electric_field_x"
]
=
&
fluxes_
[
ELECTRIC_POTENTIAL
][
0
];
outputData
[
"electric_field_y"
]
=
&
fluxes_
[
ELECTRIC_POTENTIAL
][
1
];
outputData
[
"electric_field_z"
]
=
&
fluxes_
[
ELECTRIC_POTENTIAL
][
2
];
if
(
electronDensityEqn_
==
ELECTRON_SCHRODINGER
)
{
SPAR_MAT
K
;
Array2D
<
bool
>
rhsMask
(
NUM_FIELDS
,
NUM_FLUX
);
rhsMask
=
false
;
rhsMask
(
ELECTRON_WAVEFUNCTION
,
FLUX
)
=
true
;
pair
<
FieldName
,
FieldName
>
row_col
(
ELECTRON_WAVEFUNCTION
,
ELECTRON_WAVEFUNCTION
);
atc_
->
feEngine_
->
compute_tangent_matrix
(
rhsMask
,
row_col
,
atc_
->
fields
(),
physicsModel_
,
atc_
->
element_to_material_map
(),
K
);
phiTotal_
.
reset
(
K
.
nRows
(),
1
);
const
DIAG_MAT
&
inv_dV
=
(
atc_
->
invNodeVolumes_
).
quantity
();
for
(
int
i
=
0
;
i
<
K
.
nRows
()
;
i
++
)
{
phiTotal_
(
i
,
0
)
=
0.0
;
for
(
int
j
=
0
;
j
<
K
.
nCols
()
;
j
++
)
{
phiTotal_
(
i
,
0
)
+=
K
(
i
,
j
);
}
phiTotal_
(
i
,
0
)
*=
inv_dV
(
i
,
i
);
}
outputData
[
"V_total"
]
=
&
phiTotal_
;
}
// globals
double
nSum
=
((
atc_
->
field
(
ELECTRON_DENSITY
)).
quantity
()).
col_sum
();
atc_
->
feEngine_
->
add_global
(
"total_electron_density"
,
nSum
);
#ifdef ATC_VERBOSE
// ATC::LammpsInterface::instance()->print_msg_once("... done",false,true);
#endif
}
//--------------------------------------------------------
// size_vector
//--------------------------------------------------------
int
ExtrinsicModelDriftDiffusion
::
size_vector
(
int
intrinsicSize
)
{
int
xSize
=
ExtrinsicModelTwoTemperature
::
size_vector
(
intrinsicSize
);
baseSize_
=
intrinsicSize
+
xSize
;
xSize
+=
2
;
return
xSize
;
}
//--------------------------------------------------------
// compute_vector
//--------------------------------------------------------
bool
ExtrinsicModelDriftDiffusion
::
compute_vector
(
int
n
,
double
&
value
)
{
// output[1] = total electron density
// output[2] = total joule heating
bool
match
=
ExtrinsicModelTwoTemperature
::
compute_vector
(
n
,
value
);
if
(
match
)
return
match
;
if
(
n
==
baseSize_
)
{
double
nSum
=
((
atc_
->
field
(
ELECTRON_DENSITY
)).
quantity
()).
col_sum
();
value
=
nSum
;
return
true
;
}
if
(
n
==
baseSize_
+
1
)
{
DENS_MAT
&
JE
=
rhs_
[
ELECTRON_TEMPERATURE
].
set_quantity
();
double
totalJouleHeating
=
JE
.
sum
();
value
=
totalJouleHeating
;
return
true
;
}
return
false
;
}
//--------------------------------------------------------
//--------------------------------------------------------
// Class ExtrinsicModelDriftDiffusionConvection
//--------------------------------------------------------
//--------------------------------------------------------
//--------------------------------------------------------
// Constructor
//--------------------------------------------------------
ExtrinsicModelDriftDiffusionConvection
::
ExtrinsicModelDriftDiffusionConvection
(
ExtrinsicModelManager
*
modelManager
,
ExtrinsicModelType
modelType
,
string
matFileName
)
:
ExtrinsicModelDriftDiffusion
(
modelManager
,
modelType
,
matFileName
),
cddmPoissonSolver_
(
NULL
),
baseSize_
(
0
)
{
// delete base class's version of the physics model
if
(
physicsModel_
)
delete
physicsModel_
;
if
(
modelType
==
CONVECTIVE_DRIFT_DIFFUSION_SCHRODINGER
)
{
physicsModel_
=
new
PhysicsModelDriftDiffusionConvectionSchrodinger
(
matFileName
);
electronDensityEqn_
=
ELECTRON_SCHRODINGER
;
}
else
{
physicsModel_
=
new
PhysicsModelDriftDiffusionConvection
(
matFileName
);
}
atc_
->
useConsistentMassMatrix_
(
ELECTRON_VELOCITY
)
=
false
;
atc_
->
useConsistentMassMatrix_
(
ELECTRON_TEMPERATURE
)
=
false
;
}
//--------------------------------------------------------
// Destructor
//--------------------------------------------------------
ExtrinsicModelDriftDiffusionConvection
::~
ExtrinsicModelDriftDiffusionConvection
()
{
if
(
cddmPoissonSolver_
)
delete
cddmPoissonSolver_
;
for
(
vector
<
LinearSolver
*
>::
const_iterator
iter
=
velocitySolvers_
.
begin
();
iter
!=
velocitySolvers_
.
end
();
iter
++
)
if
(
*
iter
)
delete
*
iter
;
}
//--------------------------------------------------------
// initialize
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusionConvection
::
initialize
()
{
ExtrinsicModelDriftDiffusion
::
initialize
();
nNodes_
=
atc_
->
num_nodes
();
nsd_
=
atc_
->
nsd
();
rhs_
[
ELECTRON_VELOCITY
].
reset
(
nNodes_
,
nsd_
);
atc_
->
set_fixed_nodes
();
// needed to correctly set BC data
// initialize Poisson solver
if
(
cddmPoissonSolver_
)
delete
cddmPoissonSolver_
;
Array2D
<
bool
>
rhsMask
(
NUM_FIELDS
,
NUM_FLUX
);
rhsMask
=
false
;
rhsMask
(
ELECTRIC_POTENTIAL
,
FLUX
)
=
true
;
pair
<
FieldName
,
FieldName
>
row_col
(
ELECTRIC_POTENTIAL
,
ELECTRIC_POTENTIAL
);
SPAR_MAT
stiffness
;
(
atc_
->
feEngine_
)
->
compute_tangent_matrix
(
rhsMask
,
row_col
,
atc_
->
fields
(),
physicsModel_
,
atc_
->
element_to_material_map
(),
stiffness
);
const
BC_SET
&
bcs
=
(
atc_
->
prescribedDataMgr_
->
bcs
(
ELECTRIC_POTENTIAL
))[
0
];
cddmPoissonSolver_
=
new
LinearSolver
(
stiffness
,
bcs
,
poissonSolverType_
,
-
1
,
true
);
// initialize velocity solver
const
BCS
&
velocityBcs
=
atc_
->
prescribedDataMgr_
->
bcs
(
ELECTRON_VELOCITY
);
DENS_MAT
velocityRhs
(
nNodes_
,
nsd_
);
atc_
->
compute_mass_matrix
(
ELECTRON_VELOCITY
,
physicsModel_
);
SPAR_MAT
&
velocityMassMat
=
(
atc_
->
consistentMassMats_
[
ELECTRON_VELOCITY
]).
set_quantity
();
for
(
int
i
=
0
;
i
<
nsd_
;
i
++
)
{
LinearSolver
*
myVelocitySolver
=
new
LinearSolver
(
velocityMassMat
,
velocityBcs
[
i
],
LinearSolver
::
AUTO_SOLVE
,
-
1
,
true
);
velocitySolvers_
.
push_back
(
myVelocitySolver
);
}
}
//--------------------------------------------------------
// pre initial integration
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusionConvection
::
pre_init_integrate
()
{
double
dt
=
atc_
->
lammpsInterface_
->
dt
();
double
time
=
atc_
->
time
();
int
step
=
atc_
->
step
();
if
(
step
%
fluxUpdateFreq_
!=
0
)
return
;
// set Dirchlet data
atc_
->
set_fixed_nodes
();
// set Neumann data (atc does not set these until post_final)
atc_
->
set_sources
();
// subcyle integration of fast electron variable/s
double
idt
=
dt
/
nsubcycle_
;
for
(
int
i
=
0
;
i
<
nsubcycle_
;
++
i
)
{
// update electron temperature mass matrix
atc_
->
compute_mass_matrix
(
ELECTRON_VELOCITY
,
physicsModel_
);
// update electron velocity
if
(
!
(
atc_
->
prescribedDataMgr_
)
->
all_fixed
(
ELECTRON_VELOCITY
))
{
//const BCS & bcs
// = atc_->prescribedDataMgr_->bcs(ELECTRON_VELOCITY);
Array2D
<
bool
>
rhsMask
(
NUM_FIELDS
,
NUM_FLUX
);
rhsMask
=
false
;
rhsMask
(
ELECTRON_VELOCITY
,
SOURCE
)
=
atc_
->
fieldMask_
(
ELECTRON_VELOCITY
,
SOURCE
);
rhsMask
(
ELECTRON_VELOCITY
,
FLUX
)
=
atc_
->
fieldMask_
(
ELECTRON_VELOCITY
,
FLUX
);
rhsMask
(
ELECTRON_VELOCITY
,
OPEN_SOURCE
)
=
atc_
->
fieldMask_
(
ELECTRON_VELOCITY
,
OPEN_SOURCE
);
FIELDS
rhs
;
rhs
[
ELECTRON_VELOCITY
].
reset
(
nNodes_
,
nsd_
);
atc_
->
compute_rhs_vector
(
rhsMask
,
atc_
->
fields_
,
rhs
,
atc_
->
source_integration
(),
physicsModel_
);
const
DENS_MAT
&
velocityRhs
=
rhs
[
ELECTRON_VELOCITY
].
quantity
();
// add a solver for electron momentum
DENS_MAT
&
velocity
=
(
atc_
->
field
(
ELECTRON_VELOCITY
)).
set_quantity
();
for
(
int
j
=
0
;
j
<
nsd_
;
++
j
)
{
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRON_VELOCITY
,
j
)
)
{
if
(
atc_
->
useConsistentMassMatrix_
(
ELECTRON_VELOCITY
))
{
//#ifdef ATC_PRINT_DEBUGGING
const
SPAR_MAT
&
velocityMassMat
=
(
atc_
->
consistentMassMats_
[
ELECTRON_VELOCITY
]).
quantity
();
velocityMassMat
.
print
(
"VMASS"
);
//#endif
CLON_VEC
v
=
column
(
velocity
,
j
);
const
CLON_VEC
r
=
column
(
velocityRhs
,
j
);
(
velocitySolvers_
[
j
])
->
solve
(
v
,
r
);
}
else
{
//velocityRhs.print("VRHS");
//const DIAG_MAT & velocityMassMat = (atc_->massMats_[ELECTRON_VELOCITY]).quantity();
//velocityMassMat.print("MASS");
atc_
->
apply_inverse_mass_matrix
(
velocityRhs
,
velocity
,
ELECTRON_VELOCITY
);
}
}
}
}
//atc_->set_fixed_nodes();
if
(
electronDensityEqn_
==
ELECTRON_CONTINUITY
)
{
// update continuity eqn
Array2D
<
bool
>
rhsMask
(
NUM_FIELDS
,
NUM_FLUX
);
rhsMask
=
false
;
rhsMask
(
ELECTRON_DENSITY
,
FLUX
)
=
atc_
->
fieldMask_
(
ELECTRON_DENSITY
,
FLUX
);
rhsMask
(
ELECTRON_DENSITY
,
SOURCE
)
=
atc_
->
fieldMask_
(
ELECTRON_DENSITY
,
SOURCE
);
rhsMask
(
ELECTRON_DENSITY
,
PRESCRIBED_SOURCE
)
=
atc_
->
fieldMask_
(
ELECTRON_DENSITY
,
PRESCRIBED_SOURCE
);
FIELDS
rhs
;
rhs
[
ELECTRON_DENSITY
].
reset
(
nNodes_
,
1
);
atc_
->
compute_rhs_vector
(
rhsMask
,
atc_
->
fields_
,
rhs
,
atc_
->
source_integration
(),
physicsModel_
);
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRON_DENSITY
)
)
continuityIntegrator_
->
update
(
idt
,
time
,
atc_
->
fields_
,
rhs
);
atc_
->
set_fixed_nodes
();
// solve poisson eqn for electric potential
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRIC_POTENTIAL
)
)
{
//poissonSolver_->solve(atc_->fields_,rhs_);
rhsMask
=
false
;
rhsMask
(
ELECTRIC_POTENTIAL
,
SOURCE
)
=
atc_
->
fieldMask_
(
ELECTRIC_POTENTIAL
,
SOURCE
);
rhsMask
(
ELECTRIC_POTENTIAL
,
PRESCRIBED_SOURCE
)
=
atc_
->
fieldMask_
(
ELECTRIC_POTENTIAL
,
PRESCRIBED_SOURCE
);
// FIELDS rhs;
rhs
[
ELECTRIC_POTENTIAL
].
reset
(
nNodes_
,
1
);
atc_
->
compute_rhs_vector
(
rhsMask
,
atc_
->
fields_
,
rhs
,
atc_
->
source_integration
(),
physicsModel_
);
CLON_VEC
x
=
column
((
atc_
->
field
(
ELECTRIC_POTENTIAL
)).
set_quantity
(),
0
);
const
CLON_VEC
r
=
column
(
rhs
[
ELECTRIC_POTENTIAL
].
quantity
(),
0
);
cddmPoissonSolver_
->
solve
(
x
,
r
);
}
}
else
if
(
electronDensityEqn_
==
ELECTRON_SCHRODINGER
)
{
schrodingerPoissonSolver_
->
solve
(
rhs_
,
fluxes_
);
}
atc_
->
set_fixed_nodes
();
// update electron temperature mass matrix
atc_
->
compute_mass_matrix
(
ELECTRON_TEMPERATURE
,
physicsModel_
);
// update electron temperature
if
(
!
atc_
->
prescribedDataMgr_
->
all_fixed
(
ELECTRON_TEMPERATURE
)
)
{
//if (atc_->useConsistentMassMatrix_(ELECTRON_TEMPERATURE)) {
temperatureIntegrator_
->
update
(
idt
,
time
,
atc_
->
fields_
,
rhs_
);
//}
//else { // lumped mass matrix
//}
}
atc_
->
set_fixed_nodes
();
}
}
//--------------------------------------------------------
// output
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusionConvection
::
output
(
OUTPUT_LIST
&
outputData
)
{
ExtrinsicModelDriftDiffusion
::
output
(
outputData
);
//FIELD jouleHeating(atc_->num_nodes(),1);
//set_kinetic_energy_source(atc_->fields(),jouleHeating);
outputData
[
"joule_heating"
]
=
&
(
atc_
->
extrinsic_source
(
TEMPERATURE
)).
set_quantity
();
// globals
DENS_MAT
nodalKineticEnergy
;
compute_nodal_kinetic_energy
(
nodalKineticEnergy
);
double
kineticEnergy
=
nodalKineticEnergy
.
sum
();
atc_
->
feEngine_
->
add_global
(
"total_electron_kinetic_energy"
,
kineticEnergy
);
}
//--------------------------------------------------------
// size_vector
//--------------------------------------------------------
int
ExtrinsicModelDriftDiffusionConvection
::
size_vector
(
int
intrinsicSize
)
{
int
xSize
=
ExtrinsicModelDriftDiffusion
::
size_vector
(
intrinsicSize
);
baseSize_
=
intrinsicSize
+
xSize
;
xSize
+=
1
;
return
xSize
;
}
//--------------------------------------------------------
// compute_vector
//--------------------------------------------------------
bool
ExtrinsicModelDriftDiffusionConvection
::
compute_vector
(
int
n
,
double
&
value
)
{
// output[1] = total electron kinetic energy
bool
match
=
ExtrinsicModelDriftDiffusion
::
compute_vector
(
n
,
value
);
if
(
match
)
return
match
;
if
(
n
==
baseSize_
)
{
DENS_MAT
nodalKineticEnergy
;
compute_nodal_kinetic_energy
(
nodalKineticEnergy
);
value
=
nodalKineticEnergy
.
sum
();
return
true
;
}
return
false
;
}
//--------------------------------------------------------
// compute_kinetic_energy
//--------------------------------------------------------
void
ExtrinsicModelDriftDiffusionConvection
::
compute_nodal_kinetic_energy
(
DENS_MAT
&
kineticEnergy
)
{
DENS_MAT
&
velocity
((
atc_
->
field
(
ELECTRON_VELOCITY
)).
set_quantity
());
SPAR_MAT
&
velocityMassMat
=
(
atc_
->
consistentMassMats_
[
ELECTRON_VELOCITY
]).
set_quantity
();
kineticEnergy
.
reset
(
nNodes_
,
1
);
for
(
int
j
=
0
;
j
<
nsd_
;
j
++
)
{
CLON_VEC
myVelocity
(
velocity
,
CLONE_COL
,
j
);
DENS_MAT
velocityMat
(
nNodes_
,
1
);
for
(
int
i
=
0
;
i
<
nNodes_
;
i
++
)
velocityMat
(
i
,
0
)
=
myVelocity
(
i
);
kineticEnergy
+=
velocityMat
.
mult_by_element
(
myVelocity
);
}
kineticEnergy
=
0.5
*
velocityMassMat
*
kineticEnergy
;
}
};
Event Timeline
Log In to Comment