1 // ATC Headers
2 #include "ExtrinsicModel.h"
3 #include "ExtrinsicModelTwoTemperature.h"
4 #include "ExtrinsicModelDriftDiffusion.h"
5 #include "ExtrinsicModelElectrostatic.h"
6 #include "ATC_Error.h"
7 #include "TimeIntegrator.h"
8 #include "ATC_Coupling.h"
9 #include "LammpsInterface.h"
10 #include "PrescribedDataManager.h"
11 #include "PhysicsModel.h"
12 #include <sstream>
13 
14 using std::stringstream;
15 using std::vector;
16 using std::map;
17 using std::string;
18 
19 namespace ATC {
20 
21   //--------------------------------------------------------
22   //--------------------------------------------------------
23   //  Class ExtrinsicModelManager
24   //--------------------------------------------------------
25   //--------------------------------------------------------
26 
27   //--------------------------------------------------------
28   //  Constructor
29   //--------------------------------------------------------
ExtrinsicModelManager(ATC_Coupling * atc)30   ExtrinsicModelManager::ExtrinsicModelManager(ATC_Coupling * atc) :
31     atc_(atc)
32   {
33     // do nothing
34   }
35 
36   //--------------------------------------------------------
37   //  Destructor
38   //--------------------------------------------------------
~ExtrinsicModelManager()39   ExtrinsicModelManager::~ExtrinsicModelManager()
40   {
41     vector<ExtrinsicModel *>::iterator imodel;
42     for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
43       delete *(imodel);
44   }
45 
46   //--------------------------------------------------------
47   //  modify
48   //--------------------------------------------------------
modify(int narg,char ** arg)49   bool ExtrinsicModelManager::modify(int narg, char **arg)
50   {
51     bool foundMatch = false;
52 
53     // loop over models with command
54     vector<ExtrinsicModel *>::iterator imodel;
55     for(imodel=extrinsicModels_.begin();
56         imodel!=extrinsicModels_.end(); imodel++) {
57       foundMatch = (*imodel)->modify(narg,arg);
58       if (foundMatch) break;
59     }
60 
61     return foundMatch;
62   }
63 
64   //--------------------------------------------------------
65   //  create_model
66   //--------------------------------------------------------
create_model(ExtrinsicModelType modelType,string matFileName)67   void ExtrinsicModelManager::create_model(ExtrinsicModelType modelType,
68                                            string matFileName)
69   {
70     string typeName;
71     bool validModel = model_to_string(modelType,typeName);
72     if (!validModel) {
73       throw ATC_Error("Could not create extrinsic model");
74       return;
75     }
76     ExtrinsicModel * myModel;
77     if      (modelType==TWO_TEMPERATURE) {
78       stringstream ss;
79       ss << "creating two_temperature extrinsic model";
80       ATC::LammpsInterface::instance()->print_msg_once(ss.str());
81       myModel = new ExtrinsicModelTwoTemperature
82         (this,modelType,matFileName);
83     }
84     else if (modelType==DRIFT_DIFFUSION
85          ||  modelType==DRIFT_DIFFUSION_EQUILIBRIUM
86          ||  modelType==DRIFT_DIFFUSION_SCHRODINGER
87          || modelType==DRIFT_DIFFUSION_SCHRODINGER_SLICE)
88     {
89       stringstream ss;
90       ss << "creating drift_diffusion extrinsic model";
91       ATC::LammpsInterface::instance()->print_msg_once(ss.str());
92       myModel = new ExtrinsicModelDriftDiffusion
93         (this,modelType,matFileName);
94     }
95     else if (modelType==CONVECTIVE_DRIFT_DIFFUSION
96          ||  modelType==CONVECTIVE_DRIFT_DIFFUSION_EQUILIBRIUM
97          ||  modelType==CONVECTIVE_DRIFT_DIFFUSION_SCHRODINGER) {
98       stringstream ss;
99       ss << "creating convective_drift_diffusion extrinsic model";
100       ATC::LammpsInterface::instance()->print_msg_once(ss.str());
101       myModel = new ExtrinsicModelDriftDiffusionConvection
102         (this,modelType,matFileName);
103     }
104     else if (modelType==ELECTROSTATIC || modelType==ELECTROSTATIC_EQUILIBRIUM) {
105       stringstream ss;
106       ss << "creating electrostatic extrinsic model";
107       ATC::LammpsInterface::instance()->print_msg_once(ss.str());
108       myModel = new ExtrinsicModelElectrostaticMomentum
109         (this,modelType,matFileName);
110     }
111     else if (modelType==FEM_EFIELD) {
112       stringstream ss;
113       ss << "creating fem_efield extrinsic model";
114       ATC::LammpsInterface::instance()->print_msg_once(ss.str());
115       myModel = new ExtrinsicModelElectrostatic
116         (this,modelType,matFileName);
117     } else myModel = nullptr;
118     extrinsicModels_.push_back(myModel);
119 
120      // add new fields to fields data
121      map<FieldName,int> fieldSizes;
122      myModel->num_fields(fieldSizes);
123      atc_->add_fields(fieldSizes);
124   }
125 
126   //--------------------------------------------------------
127   //  initialize
128   //--------------------------------------------------------
construct_transfers()129   void ExtrinsicModelManager::construct_transfers()
130   {
131     vector<ExtrinsicModel *>::iterator imodel;
132     for(imodel=extrinsicModels_.begin();
133         imodel!=extrinsicModels_.end(); imodel++) {
134       // initialize models
135       (*imodel)->construct_transfers();
136     }
137   }
138 
139   //--------------------------------------------------------
140   //  initialize
141   //--------------------------------------------------------
initialize()142   void ExtrinsicModelManager::initialize()
143   {
144     vector<ExtrinsicModel *>::iterator imodel;
145     for(imodel=extrinsicModels_.begin();
146         imodel!=extrinsicModels_.end(); imodel++) {
147       // initialize models
148       (*imodel)->initialize();
149     }
150   }
151 
152   //--------------------------------------------------------
153   //  get_model : access to a particular type of model
154   //--------------------------------------------------------
model(const ExtrinsicModelType type) const155   const ExtrinsicModel * ExtrinsicModelManager::model(const ExtrinsicModelType type) const {
156       vector<ExtrinsicModel *>::const_iterator imodel;
157       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++) {
158         if ((*imodel)->model_type()==type) return *imodel;
159       }
160       return nullptr;
161     }
162 
163 
164   //--------------------------------------------------------
165   //  size_vector
166   //--------------------------------------------------------
size_vector(int intrinsicSize)167   int ExtrinsicModelManager::size_vector(int intrinsicSize)
168   {
169     int extrinsicSize = 0;
170     vector<ExtrinsicModel *>::iterator imodel;
171     for(imodel=extrinsicModels_.begin();
172         imodel!=extrinsicModels_.end(); imodel++) {
173       // query all models for LAMMPS display
174       int currentSize = intrinsicSize + extrinsicSize;
175       extrinsicSize += (*imodel)->size_vector(currentSize);
176     }
177 
178     return extrinsicSize;
179   }
180 
181   //--------------------------------------------------------
182   //  compute_scalar
183   //--------------------------------------------------------
compute_scalar(void)184   double ExtrinsicModelManager::compute_scalar(void)
185   {
186     double value = 0.;
187     vector<ExtrinsicModel *>::iterator imodel;
188     for(imodel=extrinsicModels_.begin();
189         imodel!=extrinsicModels_.end(); imodel++) {
190       value += (*imodel)->compute_scalar(); // sum
191     }
192     return value;
193   }
194 
195   //--------------------------------------------------------
196   //  compute_vector
197   //--------------------------------------------------------
compute_vector(int n)198   double ExtrinsicModelManager::compute_vector(int n)
199   {
200     double value = 0.;
201     vector<ExtrinsicModel *>::iterator imodel;
202     for(imodel=extrinsicModels_.begin();
203         imodel!=extrinsicModels_.end(); imodel++) {
204       // query all models for LAMMPS display
205       if ((*imodel)->compute_vector(n,value))
206         break;
207     }
208     return value;
209   }
210 
211   //--------------------------------------------------------
212   //  finish
213   //--------------------------------------------------------
finish()214   void ExtrinsicModelManager::finish()
215   {
216     // do nothing
217   }
218 
219   //--------------------------------------------------------
220   //  pre_init_integrate
221   //--------------------------------------------------------
pre_init_integrate(ExtrinsicModelType modelType)222   void ExtrinsicModelManager::pre_init_integrate(ExtrinsicModelType modelType)
223   {
224     vector<ExtrinsicModel *>::iterator imodel;
225     if (modelType == NUM_MODELS) {// execute all the models
226       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
227         (*imodel)->pre_init_integrate();
228     }
229     else { // execute only requested type of model
230       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
231         if ((*imodel)->model_type() == modelType)
232           (*imodel)->pre_init_integrate();
233     }
234   }
235 
236   //--------------------------------------------------------
237   //  post_init_integrate
238   //--------------------------------------------------------
post_init_integrate(ExtrinsicModelType modelType)239   void ExtrinsicModelManager::post_init_integrate(ExtrinsicModelType modelType)
240   {
241     vector<ExtrinsicModel *>::iterator imodel;
242     if (modelType == NUM_MODELS) {// execute all the models
243       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
244         (*imodel)->post_init_integrate();
245     }
246     else { // execute only requested type of model
247       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
248         if ((*imodel)->model_type() == modelType)
249           (*imodel)->post_init_integrate();
250     }
251   }
252 
253   //--------------------------------------------------------
254   //  post_force
255   //--------------------------------------------------------
post_force(ExtrinsicModelType modelType)256   void ExtrinsicModelManager::post_force(ExtrinsicModelType modelType)
257   {
258     vector<ExtrinsicModel *>::iterator imodel;
259     if (modelType == NUM_MODELS) {// execute all the models
260       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
261         (*imodel)->post_force();
262     }
263     else { // execute only requested type of model
264       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
265         if ((*imodel)->model_type() == modelType)
266           (*imodel)->post_force();
267     }
268   }
269 
270   //--------------------------------------------------------
271   //  pre_final_integrate
272   //--------------------------------------------------------
pre_final_integrate(ExtrinsicModelType modelType)273   void ExtrinsicModelManager::pre_final_integrate(ExtrinsicModelType modelType)
274   {
275     vector<ExtrinsicModel *>::iterator imodel;
276     if (modelType == NUM_MODELS) {// execute all the models
277       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
278         (*imodel)->pre_final_integrate();
279     }
280     else { // execute only requested type of model
281       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
282         if ((*imodel)->model_type() == modelType)
283           (*imodel)->pre_final_integrate();
284     }
285   }
286 
287   //--------------------------------------------------------
288   //  post_final_integrate
289   //--------------------------------------------------------
post_final_integrate(ExtrinsicModelType modelType)290   void ExtrinsicModelManager::post_final_integrate(ExtrinsicModelType modelType)
291   {
292     vector<ExtrinsicModel *>::iterator imodel;
293     if (modelType == NUM_MODELS) {// execute all the models
294       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
295         (*imodel)->post_final_integrate();
296     }
297     else { // execute only requested type of model
298       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
299         if ((*imodel)->model_type() == modelType)
300           (*imodel)->post_final_integrate();
301     }
302   }
303 
304   //--------------------------------------------------------
305   //  set_sources
306   //--------------------------------------------------------
set_sources(FIELDS & fields,FIELDS & sources,ExtrinsicModelType modelType)307   void ExtrinsicModelManager::set_sources(FIELDS & fields, FIELDS & sources, ExtrinsicModelType modelType)
308   {
309     vector<ExtrinsicModel *>::iterator imodel;
310     if (modelType == NUM_MODELS) {// execute all the models
311       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
312         (*imodel)->set_sources(fields,sources);
313     }
314     else { // execute only requested type of model
315       for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
316         if ((*imodel)->model_type() == modelType)
317           (*imodel)->set_sources(fields,sources);
318     }
319   }
320 
321   //--------------------------------------------------------
322   //  output
323   //--------------------------------------------------------
output(OUTPUT_LIST & outputData)324   void ExtrinsicModelManager::output(OUTPUT_LIST & outputData)
325   {
326     vector<ExtrinsicModel *>::iterator imodel;
327     for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
328       (*imodel)->output(outputData);
329   }
330 
331   //--------------------------------------------------------
332   //--------------------------------------------------------
333   //  Class ExtrinsicModel
334   //--------------------------------------------------------
335   //--------------------------------------------------------
336 
337   //--------------------------------------------------------
338   //  Constructor
339   //--------------------------------------------------------
ExtrinsicModel(ExtrinsicModelManager * modelManager,ExtrinsicModelType modelType,string)340   ExtrinsicModel::ExtrinsicModel(ExtrinsicModelManager * modelManager,
341                                  ExtrinsicModelType modelType,
342                                  string /* matFileName */) :
343     atc_(modelManager->atc()),
344     modelManager_(modelManager),
345     modelType_(modelType),
346     physicsModel_(nullptr)
347   {
348     rhsMaskIntrinsic_.reset(NUM_FIELDS,NUM_FLUX);
349     rhsMaskIntrinsic_ = false;
350   }
351 
352   //--------------------------------------------------------
353   //  Destructor
354   //--------------------------------------------------------
~ExtrinsicModel()355   ExtrinsicModel::~ExtrinsicModel()
356   {
357     if (physicsModel_) delete physicsModel_;
358   }
359 
360   //--------------------------------------------------------
361   // initialize
362   //--------------------------------------------------------
initialize(void)363   void ExtrinsicModel::initialize(void)
364   {
365     physicsModel_->initialize();
366   }
367 
368   //--------------------------------------------------------
369   //  get_num_fields
370   //  - sets dict of fields
371   //--------------------------------------------------------
num_fields(map<FieldName,int> & fieldSizes)372   void ExtrinsicModel::num_fields(map<FieldName,int> & fieldSizes)
373   {
374     physicsModel_->num_fields(fieldSizes,atc_->fieldMask_);
375   }
376 
377 };
378