Nektar++
MMFMaxwell.cpp
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2//
3// File: MMFMaxwell.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: MMF Maxwell solve routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
36
37#include <boost/algorithm/string.hpp>
38#include <boost/algorithm/string/predicate.hpp>
39#include <iomanip>
40#include <iostream>
41
46
47#include <typeinfo>
48
49namespace Nektar
50{
51std::string MMFMaxwell::className =
53 "MMFMaxwell", MMFMaxwell::create, "MMFMaxwell equation.");
54
57 : UnsteadySystem(pSession, pGraph), MMFSystem(pSession, pGraph)
58{
59}
60
61/**
62 * @brief Initialisation object for the unsteady linear advection equation.
63 */
64void MMFMaxwell::v_InitObject(bool DeclareFields)
65{
66 // Call to the initialisation object
67 UnsteadySystem::v_InitObject(DeclareFields);
68
69 int nq = m_fields[0]->GetNpoints();
70 int shapedim = m_fields[0]->GetShapeDimension();
71 ASSERTL0(shapedim <= 2, "This solver is only for 1D lines or 2D surfaces");
72
73 m_session->LoadParameter("ElemtGroup0", m_ElemtGroup0, 0);
74 m_session->LoadParameter("ElemtGroup1", m_ElemtGroup1, 0);
75 m_session->LoadParameter("boundaryforSF", m_boundaryforSF, 0);
76 m_session->LoadParameter("PrintoutSurfaceCurrent", m_PrintoutSurfaceCurrent,
77 0);
78
79 m_session->LoadParameter("AddRotation", m_AddRotation, 0);
80
81 m_session->LoadParameter("NoInc", m_NoInc, 0);
82
83 // PML parameters
84 m_session->LoadParameter("TestPML", m_TestPML, 0);
85 m_session->LoadParameter("PMLelement", m_PMLelement, 0);
86 m_session->LoadParameter("RecPML", m_RecPML, 0);
87
88 m_session->LoadParameter("AddPML", m_AddPML, 0);
89 if (m_AddPML == 1)
90 {
92 }
93 m_session->LoadParameter("PMLorder", m_PMLorder, 3);
94
95 m_session->LoadParameter("PMLthickness", m_PMLthickness, 0.0);
96 m_session->LoadParameter("PMLstart", m_PMLstart, 0.0);
97 m_session->LoadParameter("PMLmaxsigma", m_PMLmaxsigma, 100.0);
98
99 // Point Source parmaters
100 m_session->LoadParameter("Psx", m_Psx, 0.0);
101 m_session->LoadParameter("Psy", m_Psy, 0.0);
102 m_session->LoadParameter("Psz", m_Psz, 0.0);
103 m_session->LoadParameter("PSduration", m_PSduration, 1.0);
104 m_session->LoadParameter("Gaussianradius", m_Gaussianradius, 1.0);
105
106 // Cloaking parameter
107 m_session->LoadParameter("CloakNlayer", m_CloakNlayer, 5);
108 m_session->LoadParameter("Cloakraddelta", m_Cloakraddelta, 0.0);
109
111 m_session->LoadParameter("varepsilon1", m_varepsilon[0], 1.0);
112 m_session->LoadParameter("varepsilon2", m_varepsilon[1], 1.0);
113 m_session->LoadParameter("varepsilon3", m_varepsilon[2], 1.0);
114 m_n1 = sqrt(m_varepsilon[0]);
115 m_n2 = sqrt(m_varepsilon[1]);
116 m_n3 = sqrt(m_varepsilon[2]);
117
119 m_session->LoadParameter("mu1", m_mu[0], 1.0);
120 m_session->LoadParameter("mu2", m_mu[1], 1.0);
121 m_session->LoadParameter("mu3", m_mu[2], 1.0);
122
123 Array<OneD, Array<OneD, NekDouble>> Anisotropy(shapedim);
124 for (int j = 0; j < shapedim; ++j)
125 {
126 Anisotropy[j] = Array<OneD, NekDouble>(nq, 1.0);
127 }
128
129 // Add Rectangular PML
131
132 // Compute the cross producted MF
134
135 m_session->LoadParameter("Frequency", m_freq, 1.0);
136
137 // Define TestMaxwellType
138 if (m_session->DefinesSolverInfo("TESTMAXWELLTYPE"))
139 {
140 std::string TestMaxwellTypeStr =
141 m_session->GetSolverInfo("TESTMAXWELLTYPE");
142 for (int i = 0; i < (int)SolverUtils::SIZE_TestMaxwellType; ++i)
143 {
144 if (boost::iequals(SolverUtils::TestMaxwellTypeMap[i],
145 TestMaxwellTypeStr))
146 {
148 break;
149 }
150 }
151 }
152
153 else
154 {
156 }
157
158 // Define Polarization
159 if (m_session->DefinesSolverInfo("POLTYPE"))
160 {
161 std::string PolTypeStr = m_session->GetSolverInfo("POLTYPE");
162 for (int i = 0; i < (int)SolverUtils::SIZE_PolType; ++i)
163 {
164 if (boost::iequals(SolverUtils::PolTypeMap[i], PolTypeStr))
165 {
167 break;
168 }
169 }
170 }
171 else
172 {
174 }
175
176 // Define Incident wave Type
177 if (m_session->DefinesSolverInfo("INCTYPE"))
178 {
179 std::string IncTypeStr = m_session->GetSolverInfo("INCTYPE");
180 for (int i = 0; i < (int)SolverUtils::SIZE_IncType; ++i)
181 {
182 if (boost::iequals(SolverUtils::IncTypeMap[i], IncTypeStr))
183 {
185 break;
186 }
187 }
188 }
189 else
190 {
192 }
193
194 // Define Cloak Type
195 if (m_session->DefinesSolverInfo("CLOAKTYPE"))
196 {
197 std::string CloakTypeStr = m_session->GetSolverInfo("CLOAKTYPE");
198 for (int i = 0; i < (int)SIZE_CloakType; ++i)
199 {
200 if (boost::iequals(CloakTypeMap[i], CloakTypeStr))
201 {
203 break;
204 }
205 }
206 }
207 else
208 {
210 }
211
212 // Define Source Type
213 if (m_session->DefinesSolverInfo("SOURCETYPE"))
214 {
215 std::string SourceTypeStr = m_session->GetSolverInfo("SOURCETYPE");
216 for (int i = 0; i < (int)SIZE_SourceType; ++i)
217 {
218 if (boost::iequals(SourceTypeMap[i], SourceTypeStr))
219 {
221 break;
222 }
223 }
224 }
225 else
226 {
228 }
229
230 // Compute n_timesMFFwd and m_times_timesMFFwd
232
233 // Compute vaepsilon and mu vector (m_epsveci, m_muvec0);
236 for (int k = 0; k < m_spacedim; ++k)
237 {
238 m_epsvec[k] = Array<OneD, NekDouble>(nq, 1.0);
239 m_muvec[k] = Array<OneD, NekDouble>(nq, 1.0);
240 }
241
242 Array<OneD, NekDouble> radvec(nq);
243 m_DispersiveCloak = false;
244 switch (m_CloakType)
245 {
246 case eOpticalCloak:
247 {
248 radvec = ComputeRadCloak();
250 }
251 break;
252
254 {
257
258 std::cout << "*** rad = [ " << Vmath::Vmax(nq, radvec, 1) << " , "
259 << Vmath::Vmin(nq, radvec, 1) << " ) " << std::endl;
260 }
261 break;
262
264 {
265 m_DispersiveCloak = true;
266 m_wp2Tol = 0.01;
267 radvec = ComputeRadCloak();
269
270 std::cout << "*** rad = [ " << Vmath::Vmax(nq, radvec, 1) << " , "
271 << Vmath::Vmin(nq, radvec, 1) << " ) " << std::endl;
272 std::cout << "*** wp2 = [ " << Vmath::Vmax(nq, m_wp2, 1) << " , "
273 << Vmath::Vmin(nq, m_wp2, 1) << " ) " << std::endl;
274 }
275 break;
276
277 case eMicroWaveCloak:
278 {
279 radvec = ComputeRadCloak();
281 }
282 break;
283
284 default:
285 {
287 }
288 break;
289 }
290
291 NekDouble eps1min, eps1max, eps2min, eps2max, eps3min, eps3max;
292 NekDouble mu1min, mu1max, mu2min, mu2max, mu3min, mu3max;
293
294 eps1min = Vmath::Vmin(nq, m_epsvec[0], 1);
295 eps3min = Vmath::Vmin(nq, m_epsvec[2], 1);
296 eps1max = Vmath::Vmax(nq, m_epsvec[0], 1);
297 eps3max = Vmath::Vmax(nq, m_epsvec[2], 1);
298
300 {
301 Array<OneD, NekDouble> realepsr(nq);
302 Vmath::Sadd(nq, -m_wp2Tol, m_wp2, 1, realepsr, 1);
303 Vmath::Smul(nq, 1.0 / (m_Incfreq * m_Incfreq), realepsr, 1, realepsr,
304 1);
305 Vmath::Neg(nq, realepsr, 1);
306 Vmath::Sadd(nq, 1.0, realepsr, 1, realepsr, 1);
307
308 eps2min = Vmath::Vmin(nq, realepsr, 1);
309 eps2max = Vmath::Vmax(nq, realepsr, 1);
310 }
311
312 else
313 {
314 eps2min = Vmath::Vmin(nq, m_epsvec[1], 1);
315 eps2max = Vmath::Vmax(nq, m_epsvec[1], 1);
316 }
317
318 mu1min = Vmath::Vmin(nq, m_muvec[0], 1);
319 mu2min = Vmath::Vmin(nq, m_muvec[1], 1);
320 mu3min = Vmath::Vmin(nq, m_muvec[2], 1);
321 mu1max = Vmath::Vmax(nq, m_muvec[0], 1);
322 mu2max = Vmath::Vmax(nq, m_muvec[1], 1);
323 mu3max = Vmath::Vmax(nq, m_muvec[2], 1);
324
325 std::cout << "muvec0 = " << RootMeanSquare(m_muvec[0])
326 << ", muvec1 = " << RootMeanSquare(m_muvec[1]) << std::endl;
327
328 std::cout << "*** epsvec1 = [ " << eps1min << " , " << eps1max
329 << " ], epsvec2 = [ " << eps2min << " , " << eps2max
330 << " ], epsvec3 = [ " << eps3min << " , " << eps3max << " ] "
331 << std::endl;
332 std::cout << "*** muvec1 = [ " << mu1min << " , " << mu1max
333 << " ], muvec2 = [ " << mu2min << " , " << mu2max
334 << " ], muvec3 = [ " << mu3min << " , " << mu3max << " ] "
335 << std::endl;
336
337 NekDouble dtFactor;
338 switch (m_PolType)
339 {
340 // eTransMagnetic
342 {
343 dtFactor = mu1min * eps3min;
344 if (mu1min > mu2min)
345 {
346 dtFactor = mu2min * eps3min;
347 }
348 }
349 break;
350
352 {
353 dtFactor = eps1min * mu3min;
354 if (eps1min > eps2min)
355 {
356 dtFactor = eps2min * mu3min;
357 }
358 }
359 break;
360
361 default:
362 {
363 dtFactor = 1.0;
364 }
365 break;
366 }
367 std::cout << "*** dt factor proportional to varepsilon * mu is " << dtFactor
368 << std::endl;
369
370 // Compute m_Zim and m_Yim
372
373 // Compute m_epsvecminus1 and m_muminus1
376 for (int k = 0; k < m_spacedim; ++k)
377 {
380
381 if (!m_NoInc)
382 {
383 Vmath::Sadd(nq, -1.0, m_muvec[k], 1, m_negmuvecminus1[k], 1);
384 Vmath::Sadd(nq, -1.0, m_epsvec[k], 1, m_negepsvecminus1[k], 1);
385
386 Vmath::Neg(nq, m_negmuvecminus1[k], 1);
387 Vmath::Neg(nq, m_negepsvecminus1[k], 1);
388 }
389 }
390
391 eps1min = Vmath::Vmin(nq, m_negepsvecminus1[0], 1);
392 eps2min = Vmath::Vmin(nq, m_negepsvecminus1[1], 1);
393 eps3min = Vmath::Vmin(nq, m_negepsvecminus1[2], 1);
394 eps1max = Vmath::Vmax(nq, m_negepsvecminus1[0], 1);
395 eps2max = Vmath::Vmax(nq, m_negepsvecminus1[1], 1);
396 eps3max = Vmath::Vmax(nq, m_negepsvecminus1[2], 1);
397
398 mu1min = Vmath::Vmin(nq, m_negmuvecminus1[0], 1);
399 mu2min = Vmath::Vmin(nq, m_negmuvecminus1[1], 1);
400 mu3min = Vmath::Vmin(nq, m_negmuvecminus1[2], 1);
401 mu1max = Vmath::Vmax(nq, m_negmuvecminus1[0], 1);
402 mu2max = Vmath::Vmax(nq, m_negmuvecminus1[1], 1);
403 mu3max = Vmath::Vmax(nq, m_negmuvecminus1[2], 1);
404
405 std::cout << "*** negepsvecminus1 = [ " << eps1min << " , " << eps1max
406 << " ], negepsvecminus1 = [ " << eps2min << " , " << eps2max
407 << " ], negepsvecminus1 = [ " << eps3min << " , " << eps3max
408 << " ] " << std::endl;
409 std::cout << "*** negmuvecminus1 = [ " << mu1min << " , " << mu1max
410 << " ], negmuvecminus1 = [ " << mu2min << " , " << mu2max
411 << " ], negmuvecminus1 = [ " << mu3min << " , " << mu3max << " ] "
412 << std::endl;
413
414 // Compute de^m/dt \cdot e^k
415 if (m_AddRotation)
416 {
419
421 }
422
423 // Generate Sigma Block with thicknes of m_PMLthickness and m_PMLmax
424 if (m_AddPML > 0)
425 {
427 }
428
429 // If explicit it computes RHS and PROJECTION for the time integration
431 {
434 }
435 // Otherwise it gives an error (no implicit integration)
436 else
437 {
438 ASSERTL0(false, "Implicit unsteady Advection not set up.");
439 }
440}
441
442/**
443 * @brief Unsteady linear advection equation destructor.
444 */
446{
447}
448
450{
451 ASSERTL0(m_intScheme != nullptr, "No time integration scheme.");
452
453 int i, nchk = 1;
454 int nq = GetTotPoints();
455 int nvariables = 0;
456 int nfields = m_fields.size();
457
458 if (m_intVariables.empty())
459 {
460 for (i = 0; i < nfields; ++i)
461 {
462 m_intVariables.push_back(i);
463 }
464 nvariables = nfields;
465 }
466 else
467 {
468 nvariables = m_intVariables.size();
469 }
470
471 // Set up wrapper to fields data storage.
472 Array<OneD, Array<OneD, NekDouble>> fields(nvariables);
473 Array<OneD, Array<OneD, NekDouble>> tmp(nvariables);
474
475 // Order storage to list time-integrated fields first.
476 for (i = 0; i < nvariables; ++i)
477 {
478 fields[i] = m_fields[m_intVariables[i]]->GetPhys();
479 m_fields[m_intVariables[i]]->SetPhysState(false);
480 }
481
482 // Initialise time integration scheme
483 m_intScheme->InitializeScheme(m_timestep, fields, m_time, m_ode);
484
485 // Check uniqueness of checkpoint output
486 ASSERTL0((m_checktime == 0.0 && m_checksteps == 0) ||
487 (m_checktime > 0.0 && m_checksteps == 0) ||
488 (m_checktime == 0.0 && m_checksteps > 0),
489 "Only one of IO_CheckTime and IO_CheckSteps "
490 "should be set!");
491
492 int Ntot = m_checksteps ? m_steps / m_checksteps + 1 : 0;
493
494 Array<OneD, NekDouble> TimeSeries(Ntot ? Ntot : 1);
495 Array<OneD, NekDouble> Energy(Ntot ? Ntot : 1);
496
498 bool doCheckTime = false;
499 int step = 0;
500 NekDouble intTime = 0.0;
501 NekDouble cpuTime = 0.0;
502 NekDouble elapsed = 0.0;
503
504 int cntap = 0;
505 Array<OneD, NekDouble> Ezantipod;
506 int indxantipod = 0;
507
508 switch (m_SourceType)
509 {
510 case ePointSource:
511 {
512 Ezantipod = Array<OneD, NekDouble>(
514
518
519 m_fields[0]->GetCoords(x, y, z);
520
521 NekDouble Tol = 0.000001;
523 for (i = 0; i < nq; ++i)
524 {
525 rad = sqrt((x[i] + m_Psx) * (x[i] + m_Psx) +
526 (y[i] + m_Psy) * (y[i] + m_Psy) +
527 (z[i] + m_Psz) * (z[i] + m_Psz));
528 std::cout << "rad" << rad << std::endl;
529 if (rad < Tol)
530 {
531 indxantipod = i;
532 break;
533 }
534 }
535 }
536 break;
537
538 case ePlanarSource:
539 {
541
545
546 m_fields[0]->GetCoords(x, y, z);
547
548 NekDouble Tol = 0.000001;
550 for (i = 0; i < nq; ++i)
551 {
552 rad = sqrt((x[i] - m_Psx) * (x[i] - m_Psx));
553 if (rad < Tol)
554 {
555 m_SourceVector[i] = 1.0;
556 }
557 }
558
559 std::cout << "*** Area of Planar Source = "
560 << m_fields[0]->Integral(m_SourceVector) << std::endl;
561 }
562 break;
563
564 default:
565 break;
566 }
567
568 int cntpml = 0;
569 int P1indx = 0, P2indx = 0, P3indx = 0;
573 if (m_TestPML)
574 {
578
582
583 m_fields[0]->GetCoords(x, y, z);
584
585 NekDouble Tol = 0.000001;
587 for (int i = 0; i < nq; ++i)
588 {
589 rad = sqrt((x[i] + 3.0) * (x[i] + 3.0) + (y[i]) * (y[i]));
590
591 if (rad < Tol)
592 {
593 P1indx = i;
594 break;
595 }
596 }
597
598 for (int i = 0; i < nq; ++i)
599 {
600 rad =
601 sqrt((x[i] + 3.0) * (x[i] + 3.0) + (y[i] - 1.5) * (y[i] - 1.5));
602 if (rad < Tol)
603 {
604 P2indx = i;
605 break;
606 }
607 }
608
609 for (int i = 0; i < nq; ++i)
610 {
611 rad =
612 sqrt((x[i] + 3.0) * (x[i] + 3.0) + (y[i] - 3.0) * (y[i] - 3.0));
613 if (rad < Tol)
614 {
615 P3indx = i;
616 break;
617 }
618 }
619 }
620
621 int indx;
623 {
624
625 timer.Start();
626 fields = m_intScheme->TimeIntegrate(step, m_timestep);
627 timer.Stop();
628
630 elapsed = timer.TimePerTest(1);
631 intTime += elapsed;
632 cpuTime += elapsed;
633
634 // Write out status information
635 if (m_infosteps && !((step + 1) % m_infosteps) &&
636 m_session->GetComm()->GetRank() == 0)
637 {
638 std::cout << "Steps: " << std::setw(8) << std::left << step + 1
639 << " "
640 << "Time: " << std::setw(12) << std::left << m_time;
641
642 std::stringstream ss;
643 ss << cpuTime / 60.0 << " min.";
644 std::cout << " CPU Time: " << std::setw(8) << std::left << ss.str()
645 << std::endl;
646
647 cpuTime = 0.0;
648 }
649
650 switch (m_SourceType)
651 {
652 case ePointSource:
653 {
654 if (m_time <= m_PSduration)
655 {
656 Array<OneD, NekDouble> Impulse(nq);
657 Impulse = GaussianPulse(m_time, m_Psx, m_Psy, m_Psz,
659 Vmath::Vadd(nq, &Impulse[0], 1,
660 &fields[m_intVariables[2]][0], 1,
661 &fields[m_intVariables[2]][0], 1);
662 }
663 }
664 break;
665
666 case ePlanarSource:
667 {
668 Array<OneD, NekDouble> Impulse(nq);
669 for (int i = 0; i < 3; ++i)
670 {
671 Impulse = GetIncidentField(i, m_time);
672 Vmath::Vmul(nq, m_SourceVector, 1, Impulse, 1, Impulse, 1);
673 Vmath::Vadd(nq, &Impulse[0], 1,
674 &fields[m_intVariables[i]][0], 1,
675 &fields[m_intVariables[i]][0], 1);
676 }
677 }
678 break;
679
680 default:
681 break;
682 }
683
684 // Transform data into coefficient space
685 for (i = 0; i < nvariables; ++i)
686 {
687 m_fields[m_intVariables[i]]->SetPhys(fields[i]);
688 m_fields[m_intVariables[i]]->FwdTransLocalElmt(
689 fields[i], m_fields[m_intVariables[i]]->UpdateCoeffs());
690 m_fields[m_intVariables[i]]->SetPhysState(false);
691 }
692 // for (i = 0; i < nq; ++i)
693 // std::cout << m_fields[0][0][i] <<std::endl;
694
695 // Write out checkpoint files
696 if ((m_checksteps && step && !((step + 1) % m_checksteps)) ||
697 doCheckTime)
698 {
699 indx = (step + 1) / m_checksteps;
700 TimeSeries[indx] = m_time;
701
703 {
704 Checkpoint_TotalFieldOutput(nchk, m_time, fields);
705 Checkpoint_TotPlotOutput(nchk, m_time, fields);
706 }
707 Checkpoint_PlotOutput(nchk, fields);
708 Checkpoint_EDFluxOutput(nchk, m_time, fields);
709 Checkpoint_EnergyOutput(nchk, m_time, fields);
710 Checkpoint_Output(nchk++);
711
712 Energy[indx] = ComputeEnergyDensity(fields);
713
714 std::cout << "|EHr|: F1 = " << RootMeanSquare(fields[0])
715 << ", F2 = " << RootMeanSquare(fields[1])
716 << ", F3 = " << RootMeanSquare(fields[2])
717 << ", Energy = " << Energy[indx] << std::endl;
718 if (nfields > 3)
719 {
720 std::cout << "|DBr|: D1 = " << RootMeanSquare(fields[3])
721 << ", D2 = " << RootMeanSquare(fields[4])
722 << ", D3 = " << RootMeanSquare(fields[5])
723 << std::endl;
724
725 int nTraceNumPoints = GetTraceNpoints();
726 int totbdryexp =
727 m_fields[0]->GetBndCondExpansions()[0]->GetExpSize();
728 int npts = m_fields[0]
729 ->GetBndCondExpansions()[0]
730 ->GetExp(0)
731 ->GetNumPoints(0);
732
736
737 m_fields[0]->GetCoords(x0, x1, x2);
738
739 Array<OneD, NekDouble> E1Fwd(nTraceNumPoints);
740 Array<OneD, NekDouble> E2Fwd(nTraceNumPoints);
741 Array<OneD, NekDouble> H3Fwd(nTraceNumPoints);
742
743 m_fields[0]->ExtractTracePhys(fields[0], E1Fwd);
744 m_fields[0]->ExtractTracePhys(fields[1], E2Fwd);
745 m_fields[0]->ExtractTracePhys(fields[2], H3Fwd);
746
747 int id2, cnt = 0;
748 NekDouble E1atPECloc, E1atPEC = 0.0;
749 NekDouble E2atPECloc, E2atPEC = 0.0;
750 NekDouble H3atPECloc, H3atPEC = 0.0;
751
752 Array<OneD, NekDouble> E1Fwdloc(npts);
753 Array<OneD, NekDouble> E2Fwdloc(npts);
754 Array<OneD, NekDouble> H3Fwdloc(npts);
755
756 for (int e = 0; e < totbdryexp; ++e)
757 {
758 id2 = m_fields[0]->GetTrace()->GetPhys_Offset(
759 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(
760 cnt + e));
761
762 Vmath::Vcopy(npts, &E1Fwd[id2], 1, &E1Fwdloc[0], 1);
763 Vmath::Vcopy(npts, &E2Fwd[id2], 1, &E2Fwdloc[0], 1);
764 Vmath::Vcopy(npts, &H3Fwd[id2], 1, &H3Fwdloc[0], 1);
765
766 E1atPECloc = Vmath::Vamax(npts, E1Fwdloc, 1);
767 E2atPECloc = Vmath::Vamax(npts, E2Fwdloc, 1);
768 H3atPECloc = Vmath::Vamax(npts, H3Fwdloc, 1);
769
770 if (E1atPEC < E1atPECloc)
771 {
772 E1atPEC = E1atPECloc;
773 }
774
775 if (E2atPEC < E2atPECloc)
776 {
777 E2atPEC = E2atPECloc;
778 }
779
780 if (H3atPEC < H3atPECloc)
781 {
782 H3atPEC = H3atPECloc;
783 }
784 }
785
786 std::cout << "At PEC, Max. E1 = " << E1atPEC
787 << ", E2 = " << E2atPEC << ", H3 = " << H3atPEC
788 << std::endl;
789 }
790
792 {
793 Ezantipod[cntap++] = fields[2][indxantipod];
794 }
795
796 if (m_TestPML)
797 {
798 P1[cntpml] = fields[2][P1indx];
799 P2[cntpml] = fields[2][P2indx];
800 P3[cntpml] = fields[2][P3indx];
801 cntpml++;
802 }
803 doCheckTime = false;
804 }
805
806 // Step advance
807 ++step;
808 }
809
810 // Print out summary statistics
811 if (m_checksteps && m_session->GetComm()->GetRank() == 0)
812 {
813 std::cout << "Time-integration : " << intTime << "s" << std::endl;
814
815 std::cout << "TimeSeries = " << std::endl;
816 for (int i = 0; i < m_steps / m_checksteps; ++i)
817 {
818 std::cout << TimeSeries[i] << ", ";
819 }
820 std::cout << std::endl << std::endl;
821
822 std::cout << "Energy Density = " << std::endl;
823 for (int i = 0; i < m_steps / m_checksteps; ++i)
824 {
825 std::cout << Energy[i] << ", ";
826 }
827 std::cout << std::endl << std::endl;
828
830 {
832 }
833
835 {
836 std::cout << "Ez at antipod = " << std::endl;
837 for (int i = 0; i < m_steps / m_checksteps; ++i)
838 {
839 std::cout << Ezantipod[i] << ", ";
840 }
841 std::cout << std::endl << std::endl;
842 }
843
844 if (m_TestPML)
845 {
846 std::cout << "P1 = " << std::endl;
847 for (int i = 0; i < m_steps / m_checksteps; ++i)
848 {
849 std::cout << P1[i] << ", ";
850 }
851 std::cout << std::endl << std::endl;
852
853 std::cout << "P2 = " << std::endl;
854 for (int i = 0; i < m_steps / m_checksteps; ++i)
855 {
856 std::cout << P2[i] << ", ";
857 }
858 std::cout << std::endl << std::endl;
859
860 std::cout << "P3 = " << std::endl;
861 for (int i = 0; i < m_steps / m_checksteps; ++i)
862 {
863 std::cout << P3[i] << ", ";
864 }
865 std::cout << std::endl << std::endl;
866 }
867 }
868
869 for (i = 0; i < nvariables; ++i)
870 {
871 m_fields[m_intVariables[i]]->SetPhys(fields[i]);
872 m_fields[m_intVariables[i]]->SetPhysState(true);
873 }
874
875 for (i = 0; i < nvariables; ++i)
876 {
877 m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
878 m_fields[i]->UpdateCoeffs());
879 }
880}
881
882/**
883 * @brief Compute the right-hand side for the linear advection equation.
884 *
885 * @param inarray Given fields.
886 * @param outarray Calculated solution.
887 * @param time Time.
888 */
890 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
891 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
892{
893 int i;
894 int nvar = inarray.size();
895 int ncoeffs = GetNcoeffs();
896 int nq = GetTotPoints();
897
898 Array<OneD, Array<OneD, NekDouble>> physarray(nvar);
900 for (i = 0; i < nvar; ++i)
901 {
902 physarray[i] = Array<OneD, NekDouble>(nq);
903 modarray[i] = Array<OneD, NekDouble>(ncoeffs, 0.0);
904
905 Vmath::Vcopy(nq, &inarray[i][0], 1, &physarray[i][0], 1);
906 }
907
908 for (i = 0; i < nvar; i++)
909 {
910 m_fields[i]->SetPhysState(true);
911 }
912
913 // Compute Curl
914 switch (m_TestMaxwellType)
915 {
918
919 {
920
921 // Imaginary part is computed the same as Real part
924
925 for (int i = 0; i < 3; ++i)
926 {
927 tmpin[i] = Array<OneD, NekDouble>(nq);
928 tmpout[i] = Array<OneD, NekDouble>(ncoeffs, 0.0);
929
930 Vmath::Vcopy(nq, &physarray[i][0], 1, &tmpin[i][0], 1);
931 }
932
933 WeakDGMaxwellDirDeriv(tmpin, tmpout, time);
934 AddGreenDerivCompensate(tmpin, tmpout);
935
936 for (int i = 0; i < 3; ++i)
937 {
938 // For E and H
939 Vmath::Vcopy(ncoeffs, &tmpout[i][0], 1, &modarray[i][0], 1);
940 }
941 }
942 break;
943
944 default:
945 {
946
947 WeakDGMaxwellDirDeriv(physarray, modarray, time);
948 AddGreenDerivCompensate(physarray, modarray);
949 }
950 break;
951 }
952
953 for (i = 0; i < nvar; ++i)
954 {
955 m_fields[i]->MultiplyByElmtInvMass(modarray[i], modarray[i]);
956 m_fields[i]->BwdTrans(modarray[i], outarray[i]);
957 }
958
960 {
962 for (int j = 0; j < 2; ++j)
963 {
964 F = TestMaxwellSphere(time, m_freq, 3 + j);
965 Vmath::Vadd(nq, &F[0], 1, &outarray[j][0], 1, &outarray[j][0], 1);
966 }
967 }
968
969 // Add Absorbing Boundary Conditions
970 if (m_AddPML > 0)
971 {
972 AddPML(physarray, outarray);
973 }
974
975 // Add dedt component
976 if (m_AddRotation)
977 {
978 AddCoriolis(physarray, outarray);
979 AdddedtMaxwell(physarray, outarray);
980 }
981
982 // Divide it by varepsilon or mu
983 Array<OneD, NekDouble> dFdt(nq, 0.0);
984 switch (m_TestMaxwellType)
985 {
987 {
988 Vmath::Vdiv(nq, outarray[0], 1, m_epsvec[0], 1, outarray[0], 1);
989 Vmath::Vdiv(nq, outarray[1], 1, m_muvec[0], 1, outarray[1], 1);
990 }
991 break;
992
993 // TO BE CHANGED
995 {
996 Array<OneD, NekDouble> Hxdt(nq, 0.0);
997 Array<OneD, NekDouble> Hydt(nq, 0.0);
998
999 Hxdt = TestMaxwell2DPEC(time, 10, m_PolType);
1000 Hydt = TestMaxwell2DPEC(time, 11, m_PolType);
1001
1005
1006 m_fields[0]->GetCoords(x0, x1, x2);
1007
1008 NekDouble theta, tmpx, tmpy;
1009 NekDouble uxx, uxy, uyy, detu, uti, uri;
1010 Array<OneD, NekDouble> utvec(nq, 1.0);
1011 Array<OneD, NekDouble> urvec(nq, 1.0);
1012 Array<OneD, NekDouble> tmpIN(nq);
1013
1014 // Case I: ut = 4.0, ur = 0.5
1015 // NekDouble ut=4.0;
1016 // NekDouble ur=0.5;
1017
1018 // m_fields[0]->GenerateElementVector(m_ElemtGroup1, ut, 1.0,
1019 // utvec);
1020 // m_fields[0]->GenerateElementVector(m_ElemtGroup1, ur, 1.0,
1021 // urvec);
1022
1023 // Case II: ut = 0.5, ur = 1 - 2x^2
1024 NekDouble ut = 0.5;
1025 m_fields[0]->GenerateElementVector(m_ElemtGroup1, ut, 1.0, utvec);
1026
1027 m_fields[0]->GenerateElementVector(m_ElemtGroup1, 1.0, 0.0, tmpIN);
1028
1029 for (int i = 0; i < nq; i++)
1030 {
1031 urvec[i] =
1032 tmpIN[i] * (1.0 - 2 * x0[i] * x0[i]) + (1.0 - tmpIN[i]);
1033 }
1034
1035 for (int i = 0; i < nq; ++i)
1036 {
1037 theta = atan2((x1[i] + 2.0), (x0[i] + 2.0));
1038
1039 uti = utvec[i];
1040 uri = urvec[i];
1041
1042 uxx = uti * cos(theta) * cos(theta) +
1043 uri * sin(theta) * sin(theta);
1044 uyy = uti * sin(theta) * sin(theta) +
1045 uri * cos(theta) * cos(theta);
1046 uxy = (uti - uri) * cos(theta) * sin(theta);
1047
1048 detu = uxx * uyy - uxy * uxy;
1049
1050 tmpx = outarray[0][i] + (1.0 - uxx) * Hxdt[i] - uxy * Hydt[i];
1051 tmpy = outarray[1][i] - uxy * Hxdt[i] + (1.0 - uyy) * Hydt[i];
1052
1053 outarray[0][i] = (1 / detu) * (uyy * tmpx - uxy * tmpy);
1054 outarray[1][i] = (1 / detu) * (-uxy * tmpx + uxx * tmpy);
1055 }
1056 }
1057 break;
1058
1062 {
1063 switch (m_PolType)
1064 {
1066 {
1068 {
1069 dFdt = TestMaxwell2DPEC(time, 10, m_PolType);
1070 Vmath::Vvtvp(nq, m_negmuvecminus1[0], 1, dFdt, 1,
1071 outarray[0], 1, outarray[0], 1);
1072
1073 dFdt = TestMaxwell2DPEC(time, 11, m_PolType);
1074 Vmath::Vvtvp(nq, m_negmuvecminus1[1], 1, dFdt, 1,
1075 outarray[1], 1, outarray[1], 1);
1076
1077 dFdt = TestMaxwell2DPEC(time, 12, m_PolType);
1078 Vmath::Vvtvp(nq, m_negepsvecminus1[2], 1, dFdt, 1,
1079 outarray[2], 1, outarray[2], 1);
1080 }
1081
1083 {
1084 dFdt = GetIncidentField(10, time);
1085 Vmath::Vvtvp(nq, m_negmuvecminus1[0], 1, dFdt, 1,
1086 outarray[0], 1, outarray[0], 1);
1087
1088 dFdt = GetIncidentField(11, time);
1089 Vmath::Vvtvp(nq, m_negmuvecminus1[1], 1, dFdt, 1,
1090 outarray[1], 1, outarray[1], 1);
1091
1092 dFdt = GetIncidentField(12, time);
1093 Vmath::Vvtvp(nq, m_negepsvecminus1[2], 1, dFdt, 1,
1094 outarray[2], 1, outarray[2], 1);
1095 }
1096
1097 Vmath::Vdiv(nq, outarray[0], 1, m_muvec[0], 1, outarray[0],
1098 1);
1099 Vmath::Vdiv(nq, outarray[1], 1, m_muvec[1], 1, outarray[1],
1100 1);
1101 Vmath::Vdiv(nq, outarray[2], 1, m_epsvec[2], 1, outarray[2],
1102 1);
1103 }
1104 break;
1105
1107 {
1109 {
1110 // (I - \mu^i) d F^{inc} / dt
1111 dFdt = TestMaxwell2DPEC(time, 10, m_PolType);
1112 Vmath::Vvtvp(nq, m_negepsvecminus1[0], 1, dFdt, 1,
1113 outarray[0], 1, outarray[0], 1);
1114
1115 dFdt = TestMaxwell2DPEC(time, 11, m_PolType);
1116 Vmath::Vvtvp(nq, m_negepsvecminus1[1], 1, dFdt, 1,
1117 outarray[1], 1, outarray[1], 1);
1118
1119 dFdt = TestMaxwell2DPEC(time, 12, m_PolType);
1120 Vmath::Vvtvp(nq, m_negmuvecminus1[2], 1, dFdt, 1,
1121 outarray[2], 1, outarray[2], 1);
1122 }
1123
1125 {
1126 dFdt = GetIncidentField(10, time);
1127 Vmath::Vvtvp(nq, m_negepsvecminus1[0], 1, dFdt, 1,
1128 outarray[0], 1, outarray[0], 1);
1129
1130 // Add - wp^2 \int E_2^{inc}
1131 dFdt = GetIncidentField(21, time);
1133 {
1134 Vmath::Vmul(nq, m_wp2, 1, dFdt, 1, dFdt, 1);
1135 Vmath::Vsub(nq, outarray[1], 1, dFdt, 1,
1136 outarray[1], 1);
1137 }
1138
1139 else
1140 {
1141 Vmath::Vvtvp(nq, m_negepsvecminus1[1], 1, dFdt, 1,
1142 outarray[1], 1, outarray[1], 1);
1143 }
1144
1145 dFdt = GetIncidentField(12, time);
1146 Vmath::Vvtvp(nq, m_negmuvecminus1[2], 1, dFdt, 1,
1147 outarray[2], 1, outarray[2], 1);
1148 }
1149
1150 Vmath::Vdiv(nq, outarray[0], 1, m_epsvec[0], 1, outarray[0],
1151 1);
1152 Vmath::Vdiv(nq, outarray[1], 1, m_epsvec[1], 1, outarray[1],
1153 1);
1154 Vmath::Vdiv(nq, outarray[2], 1, m_muvec[2], 1, outarray[2],
1155 1);
1156 }
1157 break;
1158
1159 default:
1160 break;
1161 }
1162 }
1163 break; // case SolverUtils::eTestMaxwell2DPEC:
1164
1165 default:
1166 break;
1167
1168 } // switch(m_TestMaxwellType)
1169}
1170
1172 const Array<OneD, const Array<OneD, NekDouble>> &physarray,
1173 Array<OneD, Array<OneD, NekDouble>> &outarray)
1174{
1175 // routine works for both primitive and conservative formulations
1176 int ncoeffs = outarray[0].size();
1177 int nq = physarray[0].size();
1178
1179 Array<OneD, NekDouble> tmp(nq);
1180 Array<OneD, NekDouble> tmpc(ncoeffs);
1181
1183 for (int j = 0; j < m_shapedim; ++j)
1184 {
1185 fluxvector[j] = Array<OneD, NekDouble>(nq);
1186 }
1187
1188 // m_CurlMF[0][0] = e^3 \cdot (\nabla \times e^1) [ NEW m_CurlMF[0][2] ]
1189 // m_CurlMF[0][1] = 0.0
1190 // m_CurlMF[1][0] = 0.0,
1191 // m_CurlMF[1][1] = e^3 \cdot (\nabla \times e^2) [ NEW m_CurlMF[1][2] ]
1192 // m_CurlMF[2][0] = e^1 \cdot (\nabla \times e^3) [ NEW m_CurlMF[2][0] ]
1193 // m_CurlMF[2][1] = e^2 \cdot (\nabla \times e^3) [ NEW m_CurlMF[2][1] ]
1194
1195 int var;
1196
1197 switch (m_TestMaxwellType)
1198 {
1206 {
1207 var = 0;
1208 GetMaxwellFluxVector(var, physarray, fluxvector);
1209 Vmath::Vmul(nq, &fluxvector[0][0], 1, &m_CurlMF[0][2][0], 1,
1210 &tmp[0], 1);
1211 m_fields[var]->IProductWRTBase(tmp, tmpc);
1212 Vmath::Vadd(ncoeffs, tmpc, 1, outarray[var], 1, outarray[var], 1);
1213
1214 var = 1;
1215 GetMaxwellFluxVector(var, physarray, fluxvector);
1216 Vmath::Vmul(nq, &fluxvector[1][0], 1, &m_CurlMF[1][2][0], 1,
1217 &tmp[0], 1);
1218 Vmath::Neg(nq, tmp, 1);
1219 m_fields[var]->IProductWRTBase(tmp, tmpc);
1220 Vmath::Vadd(ncoeffs, tmpc, 1, outarray[var], 1, outarray[var], 1);
1221
1222 var = 2;
1223 GetMaxwellFluxVector(var, physarray, fluxvector);
1224 Vmath::Vmul(nq, &fluxvector[0][0], 1, &m_CurlMF[2][0][0], 1,
1225 &tmp[0], 1);
1226 Vmath::Vvtvm(nq, &fluxvector[1][0], 1, &m_CurlMF[2][1][0], 1,
1227 &tmp[0], 1, &tmp[0], 1);
1228 m_fields[var]->IProductWRTBase(tmp, tmpc);
1229 Vmath::Vadd(ncoeffs, tmpc, 1, outarray[var], 1, outarray[var], 1);
1230 }
1231 break;
1232
1233 default:
1234 break;
1235 }
1236}
1237
1238/**
1239 * @brief Calculate weak DG advection in the form \f$ \langle\phi,
1240 * \hat{F}\cdot n\rangle - (\nabla \phi \cdot F) \f$
1241 *
1242 * @param InField Fields.
1243 * @param OutField Storage for result.
1244 * @param NumericalFluxIncludesNormal Default: true.
1245 * @param InFieldIsPhysSpace Default: false.
1246 * @param nvariables Number of fields.
1247 */
1249 const Array<OneD, const Array<OneD, NekDouble>> &InField,
1250 Array<OneD, Array<OneD, NekDouble>> &OutField, const NekDouble time)
1251{
1252 int i;
1253 int nq = GetNpoints();
1254 int ncoeffs = GetNcoeffs();
1255 int nTracePointsTot = GetTraceNpoints();
1256 int nvar = 3;
1257
1259 for (i = 0; i < m_shapedim; ++i)
1260 {
1261 fluxvector[i] = Array<OneD, NekDouble>(nq);
1262 }
1263
1264 Array<OneD, Array<OneD, NekDouble>> physfield(nvar);
1265 for (i = 0; i < nvar; ++i)
1266 {
1267 physfield[i] = InField[i];
1268 }
1269
1270 Array<OneD, NekDouble> tmpc(ncoeffs);
1271 for (i = 0; i < nvar; ++i)
1272 {
1273 GetMaxwellFluxVector(i, physfield, fluxvector);
1274
1275 OutField[i] = Array<OneD, NekDouble>(ncoeffs, 0.0);
1276 for (int j = 0; j < m_shapedim; ++j)
1277 {
1278 // Directional derivation with respect to the j'th moving frame
1279 // tmp_j = ( \nabla \phi, fluxvector[j] \mathbf{e}^j )
1280 m_fields[i]->IProductWRTDirectionalDerivBase(m_CrossProductMF[j],
1281 fluxvector[j], tmpc);
1282 Vmath::Vadd(ncoeffs, &tmpc[0], 1, &OutField[i][0], 1,
1283 &OutField[i][0], 1);
1284 }
1285 }
1286
1287 // V the numerical flux and add to the modal coeffs
1288 // if the NumericalFlux function does not include the
1289 // normal in the output
1290 Array<OneD, Array<OneD, NekDouble>> numfluxFwd(nvar);
1291 Array<OneD, Array<OneD, NekDouble>> numfluxBwd(nvar);
1292
1293 for (i = 0; i < nvar; ++i)
1294 {
1295 numfluxFwd[i] = Array<OneD, NekDouble>(nTracePointsTot, 0.0);
1296 numfluxBwd[i] = Array<OneD, NekDouble>(nTracePointsTot, 0.0);
1297 }
1298
1299 // Evaluate numerical flux in physical space which may in
1300 // general couple all component of vectors
1301 NumericalMaxwellFlux(physfield, numfluxFwd, numfluxBwd, time);
1302
1303 // Evaulate <\phi, \hat{F}\cdot n> - OutField[i]
1304 for (i = 0; i < nvar; ++i)
1305 {
1306 Vmath::Neg(ncoeffs, OutField[i], 1);
1307 m_fields[i]->AddFwdBwdTraceIntegral(numfluxFwd[i], numfluxBwd[i],
1308 OutField[i]);
1309 m_fields[i]->SetPhysState(false);
1310 }
1311}
1312
1313/**
1314 * @brief Compute the projection for the linear advection equation.
1315 *
1316 * @param inarray Given fields.
1317 * @param outarray Calculated solution.
1318 * @param time Time.
1319 */
1321 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1322 Array<OneD, Array<OneD, NekDouble>> &outarray,
1323 [[maybe_unused]] const NekDouble time)
1324{
1325 int var = inarray.size();
1326
1327 if (inarray != outarray)
1328 {
1329 int nq = GetNpoints();
1330 for (int i = 0; i < var; ++i)
1331 {
1332 Vmath::Vcopy(nq, inarray[i], 1, outarray[i], 1);
1333 }
1334 }
1335}
1336
1338 bool dumpInitialConditions,
1339 [[maybe_unused]] const int domain)
1340{
1341 int nq = GetTotPoints();
1342 int nvar = m_fields.size();
1343
1344 switch (m_TestMaxwellType)
1345 {
1347 {
1348 m_fields[0]->SetPhys(TestMaxwell1D(initialtime, 0));
1349 m_fields[1]->SetPhys(TestMaxwell1D(initialtime, 1));
1350 }
1351 break;
1352
1355 {
1356 m_fields[0]->SetPhys(TestMaxwell2DPEC(initialtime, 0, m_PolType));
1357 m_fields[1]->SetPhys(TestMaxwell2DPEC(initialtime, 1, m_PolType));
1358 m_fields[2]->SetPhys(TestMaxwell2DPEC(initialtime, 2, m_PolType));
1359 }
1360 break;
1361
1363 {
1364 m_fields[0]->SetPhys(TestMaxwell2DPMC(initialtime, 0, m_PolType));
1365 m_fields[1]->SetPhys(TestMaxwell2DPMC(initialtime, 1, m_PolType));
1366 m_fields[2]->SetPhys(TestMaxwell2DPMC(initialtime, 2, m_PolType));
1367 }
1368 break;
1369
1372 {
1373 Array<OneD, NekDouble> Zeros(nq, 0.0);
1374
1375 for (int i = 0; i < nvar; i++)
1376 {
1377 m_fields[i]->SetPhys(Zeros);
1378 }
1379 }
1380 break;
1381
1383 {
1384 m_fields[0]->SetPhys(TestMaxwellSphere(initialtime, m_freq, 0));
1385 m_fields[1]->SetPhys(TestMaxwellSphere(initialtime, m_freq, 1));
1386 m_fields[2]->SetPhys(TestMaxwellSphere(initialtime, m_freq, 2));
1387 }
1388 break;
1389
1391 {
1392 m_fields[2]->SetPhys(GaussianPulse(initialtime, m_Psx, m_Psy, m_Psz,
1394 }
1395 break;
1396
1397 default:
1398 break;
1399 }
1400
1401 // forward transform to fill the modal coeffs
1402 for (int i = 0; i < nvar; ++i)
1403 {
1404 m_fields[i]->SetPhysState(true);
1405 m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1406 m_fields[i]->UpdateCoeffs());
1407 }
1408
1409 if (dumpInitialConditions)
1410 {
1411 std::string outname = m_sessionName + "_initial.chk";
1412 WriteFld(outname);
1413
1415 for (int i = 0; i < nvar; ++i)
1416 {
1417 fields[i] = m_fields[i]->GetPhys();
1418 }
1419
1420 Checkpoint_PlotOutput(0, fields);
1421 }
1422}
1423
1425 Array<OneD, NekDouble> &outfield,
1426 const NekDouble time)
1427{
1428 int nq = m_fields[0]->GetNpoints();
1429 outfield = Array<OneD, NekDouble>(nq);
1430
1431 switch (m_TestMaxwellType)
1432 {
1434 {
1435 outfield = TestMaxwell1D(time, field);
1436 }
1437 break;
1438
1441 {
1442 outfield = TestMaxwell2DPEC(time, field, m_PolType);
1443 }
1444 break;
1445
1447 {
1448 outfield = TestMaxwell2DPMC(time, field, m_PolType);
1449 }
1450 break;
1451
1453 {
1454 outfield = TestMaxwellSphere(time, m_freq, field);
1455 }
1456 break;
1457
1458 default:
1459 {
1460 outfield = Array<OneD, NekDouble>(nq, 0.0);
1461 }
1462 break;
1463 }
1464}
1465
1467 unsigned int field)
1468{
1469 int nq = m_fields[0]->GetNpoints();
1470
1474
1475 m_fields[0]->GetCoords(x0, x1, x2);
1476
1479
1480 // Derive the frequency \omega
1481 NekDouble omega;
1482 NekDouble Tol = 0.000000001;
1483 if (fabs(m_n1 - m_n2) < Tol)
1484 {
1485 omega = m_pi / m_n1;
1486 }
1487
1488 else
1489 {
1490 omega = 2.0 * m_pi / m_n2;
1491
1492 NekDouble newomega, F, Fprime;
1493 for (int i = 0; i < 10000; ++i)
1494 {
1495 F = m_n1 * tan(m_n2 * omega) + m_n2 * tan(m_n1 * omega);
1496 Fprime = m_n1 * m_n2 *
1497 (1.0 / cos(m_n2 * omega) / cos(m_n2 * omega) +
1498 1.0 / cos(m_n1 * omega) / cos(m_n1 * omega));
1499
1500 newomega = omega - F / Fprime;
1501
1502 if (fabs(newomega - omega) > Tol)
1503 {
1504 omega = newomega;
1505 }
1506
1507 else
1508 {
1509 break;
1510 }
1511 }
1512 }
1513
1514 // Generate A^k and B^k
1515 std::complex<double> im = sqrt(std::complex<double>(-1));
1516 std::complex<double> A1, A2, B1, B2;
1517 std::complex<double> Ak, Bk, nk;
1518 std::complex<double> Ec, Hc;
1519
1520 A1 = m_n2 * cos(m_n2 * omega) / (m_n1 * cos(m_n1 * omega));
1521 A2 = exp(-1.0 * im * omega * (m_n1 + m_n2));
1522 B1 = A1 * exp(-2.0 * im * m_n1 * omega);
1523 B2 = A2 * exp(2.0 * im * m_n2 * omega);
1524
1525 for (int i = 0; i < nq; ++i)
1526 {
1527 if (x0[i] > 0)
1528 {
1529 Ak = A2;
1530 Bk = B2;
1531 nk = m_n2;
1532 }
1533
1534 else
1535 {
1536 Ak = A1;
1537 Bk = B1;
1538 nk = m_n1;
1539 }
1540
1541 Ec = (Ak * exp(im * nk * omega * x0[i]) -
1542 Bk * exp(-im * nk * omega * x0[i])) *
1543 exp(im * omega * time);
1544 Hc = nk *
1545 (Ak * exp(im * nk * omega * x0[i]) +
1546 Bk * exp(-im * nk * omega * x0[i])) *
1547 exp(im * omega * time);
1548
1549 E[i] = Ec.real();
1550 H[i] = Hc.real();
1551 }
1552
1553 Array<OneD, NekDouble> outfield;
1554 switch (field)
1555 {
1556 case (0):
1557 {
1558 outfield = E;
1559 }
1560 break;
1561
1562 case (1):
1563 {
1564 outfield = H;
1565 }
1566 break;
1567 }
1568
1569 return outfield;
1570}
1571
1573 const NekDouble time, unsigned int field,
1574 const SolverUtils::PolType Polarization)
1575{
1576 int nq = m_fields[0]->GetNpoints();
1577
1581
1582 m_fields[0]->GetCoords(x0, x1, x2);
1583
1584 NekDouble freqm = 1.0, freqn = 1.0;
1585 NekDouble omega = m_pi * sqrt(freqm * freqm + freqn * freqn);
1586 NekDouble mpi = freqm * m_pi;
1587 NekDouble npi = freqn * m_pi;
1588
1592 Array<OneD, NekDouble> dF1dt(nq);
1593 Array<OneD, NekDouble> dF2dt(nq);
1594 Array<OneD, NekDouble> dFzdt(nq);
1595 NekDouble Fx, Fy, dFxdt, dFydt;
1596
1597 for (int i = 0; i < nq; ++i)
1598 {
1599 switch (Polarization)
1600 {
1602 {
1603 Fx = -1.0 * (npi / omega) * sin(mpi * x0[i]) *
1604 cos(npi * x1[i]) * sin(omega * time);
1605 Fy = (mpi / omega) * cos(mpi * x0[i]) * sin(npi * x1[i]) *
1606 sin(omega * time);
1607
1608 F1[i] =
1609 Fx * m_movingframes[0][i] + Fy * m_movingframes[0][i + nq];
1610 F2[i] =
1611 Fx * m_movingframes[1][i] + Fy * m_movingframes[1][i + nq];
1612 Fz[i] = sin(mpi * x0[i]) * sin(npi * x1[i]) * cos(omega * time);
1613
1614 dFxdt = (npi)*sin(mpi * x0[i]) * cos(npi * x1[i]) *
1615 cos(omega * time);
1616 dFydt = -1.0 * (mpi)*cos(mpi * x0[i]) * sin(npi * x1[i]) *
1617 cos(omega * time);
1618
1619 dF1dt[i] = dFxdt * m_movingframes[0][i] +
1620 dFydt * m_movingframes[0][i + nq];
1621 dF2dt[i] = dFxdt * m_movingframes[1][i] +
1622 dFydt * m_movingframes[1][i + nq];
1623 dFzdt[i] = omega * sin(mpi * x0[i]) * sin(npi * x1[i]) *
1624 sin(omega * time);
1625 }
1626 break;
1627
1629 {
1630 Fx = -1.0 * (npi / omega) * cos(mpi * x0[i]) *
1631 sin(npi * x1[i]) * sin(omega * time);
1632 Fy = (mpi / omega) * sin(mpi * x0[i]) * cos(npi * x1[i]) *
1633 sin(omega * time);
1634
1635 F1[i] =
1636 Fx * m_movingframes[0][i] + Fy * m_movingframes[0][i + nq];
1637 F2[i] =
1638 Fx * m_movingframes[1][i] + Fy * m_movingframes[1][i + nq];
1639 Fz[i] = cos(mpi * x0[i]) * cos(npi * x1[i]) * cos(omega * time);
1640
1641 dFxdt = (npi)*cos(mpi * x0[i]) * sin(npi * x1[i]) *
1642 cos(omega * time);
1643 dFydt = -1.0 * (mpi)*sin(mpi * x0[i]) * cos(npi * x1[i]) *
1644 cos(omega * time);
1645
1646 dF1dt[i] = dFxdt * m_movingframes[0][i] +
1647 dFydt * m_movingframes[0][i + nq];
1648 dF2dt[i] = dFxdt * m_movingframes[1][i] +
1649 dFydt * m_movingframes[1][i + nq];
1650 dFzdt[i] = omega * cos(mpi * x0[i]) * cos(npi * x1[i]) *
1651 sin(omega * time);
1652 }
1653 break;
1654
1655 default:
1656 break;
1657 }
1658 }
1659
1660 Array<OneD, NekDouble> outfield;
1661 switch (field)
1662 {
1663 case (0):
1664 {
1665 outfield = F1;
1666 }
1667 break;
1668
1669 case (1):
1670 {
1671 outfield = F2;
1672 }
1673 break;
1674
1675 case (2):
1676 {
1677 outfield = Fz;
1678 }
1679 break;
1680
1681 case (10):
1682 {
1683 outfield = dF1dt;
1684 }
1685 break;
1686
1687 case (11):
1688 {
1689 outfield = dF2dt;
1690 }
1691 break;
1692
1693 case (12):
1694 {
1695 outfield = dFzdt;
1696 }
1697 break;
1698 }
1699
1700 return outfield;
1701}
1702
1704 const NekDouble time, unsigned int field,
1705 const SolverUtils::PolType Polarization)
1706{
1707 int nq = m_fields[0]->GetNpoints();
1708
1712
1713 m_fields[0]->GetCoords(x0, x1, x2);
1714
1715 NekDouble freqm = 1.0, freqn = 1.0;
1716 NekDouble omega = m_pi * sqrt(freqm * freqm + freqn * freqn);
1717 NekDouble mpi = freqm * m_pi;
1718 NekDouble npi = freqn * m_pi;
1719
1723 NekDouble Fx, Fy;
1724
1725 for (int i = 0; i < nq; ++i)
1726 {
1727 switch (Polarization)
1728 {
1730 {
1731 Fx = (npi / omega) * cos(mpi * x0[i]) * sin(npi * x1[i]) *
1732 sin(omega * time);
1733 Fy = -(mpi / omega) * sin(mpi * x0[i]) * cos(npi * x1[i]) *
1734 sin(omega * time);
1735
1736 F1[i] =
1737 Fx * m_movingframes[0][i] + Fy * m_movingframes[0][i + nq];
1738 F2[i] =
1739 Fx * m_movingframes[1][i] + Fy * m_movingframes[1][i + nq];
1740 Fz[i] = cos(mpi * x0[i]) * cos(npi * x1[i]) * cos(omega * time);
1741 }
1742 break;
1743
1745 {
1746 Fx = (npi / omega) * sin(mpi * x0[i]) * cos(npi * x1[i]) *
1747 sin(omega * time);
1748 Fy = -(mpi / omega) * cos(mpi * x0[i]) * sin(npi * x1[i]) *
1749 sin(omega * time);
1750
1751 F1[i] =
1752 Fx * m_movingframes[0][i] + Fy * m_movingframes[0][i + nq];
1753 F2[i] =
1754 Fx * m_movingframes[1][i] + Fy * m_movingframes[1][i + nq];
1755 Fz[i] = sin(mpi * x0[i]) * sin(npi * x1[i]) * cos(omega * time);
1756 }
1757 break;
1758
1759 default:
1760 break;
1761 }
1762 }
1763
1764 Array<OneD, NekDouble> outfield;
1765 switch (field)
1766 {
1767 case (0):
1768 {
1769 outfield = F1;
1770 }
1771 break;
1772
1773 case (1):
1774 {
1775 outfield = F2;
1776 }
1777 break;
1778
1779 case (2):
1780 {
1781 outfield = Fz;
1782 }
1783 break;
1784 }
1785
1786 return outfield;
1787}
1788
1790 const NekDouble omega,
1791 unsigned int field)
1792{
1793 int nq = m_fields[0]->GetTotPoints();
1794
1795 Array<OneD, NekDouble> outfield(nq);
1796
1800
1801 m_fields[0]->GetCoords(x, y, z);
1802
1808
1809 Array<OneD, NekDouble> curlv(nq);
1812 for (int i = 0; i < m_spacedim; ++i)
1813 {
1814 velvec[i] = Array<OneD, NekDouble>(nq, 0.0);
1815 Fvec[i] = Array<OneD, NekDouble>(nq, 0.0);
1816 }
1817
1818 NekDouble xj, yj, zj, sin_varphi, cos_varphi, sin_theta, cos_theta;
1819 NekDouble vth, vphi, Fth, Fphi;
1820 for (int i = 0; i < nq; i++)
1821 {
1822 xj = x[i];
1823 yj = y[i];
1824 zj = z[i];
1825
1826 CartesianToSpherical(xj, yj, zj, sin_varphi, cos_varphi, sin_theta,
1827 cos_theta);
1828
1829 vth = -4.0 * sin_varphi * cos_varphi * cos_theta * cos_theta *
1830 cos_theta * sin_theta;
1831 vphi =
1832 -1.0 * sin_varphi * sin_varphi * cos_theta * cos_theta * cos_theta;
1833 velvec[0][i] = -vth * sin_theta * cos_varphi - vphi * sin_varphi;
1834 velvec[1][i] = -vth * sin_theta * sin_varphi + vphi * cos_varphi;
1835 velvec[2][i] = vth * cos_theta;
1836
1837 E3[i] = (-4.0 * cos_theta * cos_theta * sin_theta * cos_varphi *
1838 cos_varphi) *
1839 (1.0 / omega * sin(omega * time));
1840
1841 Fth = -omega * vth -
1842 (8.0 / omega) * cos_theta * sin_theta * cos_varphi * sin_varphi;
1843 Fphi = -omega * vphi +
1844 (4.0 / omega) * cos_varphi * cos_varphi * cos_theta *
1845 (2.0 * sin_theta * sin_theta - cos_theta * cos_theta);
1846 Fvec[0][i] = -Fth * sin_theta * cos_varphi - Fphi * sin_varphi;
1847 Fvec[1][i] = -Fth * sin_theta * sin_varphi + Fphi * cos_varphi;
1848 Fvec[2][i] = Fth * cos_theta;
1849 }
1850
1851 H1 = CartesianToMovingframes(velvec, 0);
1852 H2 = CartesianToMovingframes(velvec, 1);
1853
1854 Vmath::Smul(nq, cos(omega * time), H1, 1, H1, 1);
1855 Vmath::Smul(nq, cos(omega * time), H2, 1, H2, 1);
1856
1857 F1 = CartesianToMovingframes(Fvec, 0);
1858 F2 = CartesianToMovingframes(Fvec, 1);
1859
1860 Vmath::Smul(nq, sin(omega * time), F1, 1, F1, 1);
1861 Vmath::Smul(nq, sin(omega * time), F2, 1, F2, 1);
1862
1863 switch (field)
1864 {
1865 // return H1
1866 case 0:
1867 {
1868 outfield = H1;
1869 }
1870 break;
1871
1872 case 1:
1873 {
1874 outfield = H2;
1875 }
1876 break;
1877
1878 case 2:
1879 {
1880 outfield = E3;
1881 }
1882 break;
1883
1884 case 3:
1885 {
1886 outfield = F1;
1887 }
1888 break;
1889
1890 case 4:
1891 {
1892 outfield = F2;
1893 }
1894 break;
1895
1896 default:
1897 break;
1898 }
1899
1900 return outfield;
1901}
1902
1904 Array<OneD, Array<OneD, NekDouble>> &fields, const int time)
1905{
1906 int nq = m_fields[0]->GetTotPoints();
1907 int nTraceNumPoints = GetTraceTotPoints();
1908
1909 int totbdryexp =
1910 m_fields[0]->GetBndCondExpansions()[m_boundaryforSF]->GetExpSize();
1911 int npts = m_fields[0]
1912 ->GetBndCondExpansions()[m_boundaryforSF]
1913 ->GetExp(0)
1914 ->GetNumPoints(0);
1915 int totnpts = totbdryexp * npts;
1916
1917 Array<OneD, NekDouble> Jphi(totnpts);
1918 Array<OneD, NekDouble> Jrad(totnpts);
1919 Array<OneD, NekDouble> Jcurrent(totnpts);
1920
1921 Array<OneD, NekDouble> phiFwd(nTraceNumPoints);
1922 Array<OneD, NekDouble> radFwd(nTraceNumPoints);
1923
1924 // Compute phiFwd = acos(-x/r) along the trace
1928
1929 m_fields[0]->GetCoords(x, y, z);
1930
1931 Array<OneD, NekDouble> xFwd(nTraceNumPoints);
1932 Array<OneD, NekDouble> yFwd(nTraceNumPoints);
1933
1934 m_fields[0]->ExtractTracePhys(x, xFwd);
1935 m_fields[0]->ExtractTracePhys(y, yFwd);
1936
1937 for (int i = 0; i < nTraceNumPoints; ++i)
1938 {
1939 radFwd[i] = sqrt(xFwd[i] * xFwd[i] / m_MMFfactors[0] / m_MMFfactors[0] +
1940 yFwd[i] * yFwd[i] / m_MMFfactors[1] / m_MMFfactors[1]);
1941 phiFwd[i] = atan2(yFwd[i] / radFwd[i], -1.0 * xFwd[i] / radFwd[i]);
1942 }
1943
1944 Array<OneD, NekDouble> ntimesHFwd(nTraceNumPoints);
1945 ntimesHFwd = ComputeSurfaceCurrent(time, fields);
1946
1947 // The surface for current should be the first boundary
1948 int id2, cnt = 0;
1949 for (int e = 0; e < totbdryexp; ++e)
1950 {
1951 id2 = m_fields[0]->GetTrace()->GetPhys_Offset(
1952 m_fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt + e));
1953
1954 Vmath::Vcopy(npts, &phiFwd[id2], 1, &Jphi[e * npts], 1);
1955 Vmath::Vcopy(npts, &radFwd[id2], 1, &Jrad[e * npts], 1);
1956 Vmath::Vcopy(npts, &ntimesHFwd[id2], 1, &Jcurrent[e * npts], 1);
1957 }
1958
1959 // Vmath::Vmul(totnpts, tmpr, 1, tmpr, 1, Jcurrent, 1);
1960 // Vmath::Vvtvp(totnpts, tmpi, 1, tmpi, 1, Jcurrent, 1, Jcurrent, 1);
1961 // Vmath::Vsqrt(totnpts, Jcurrent, 1, Jcurrent, 1);
1962
1963 std::cout << "========================================================"
1964 << std::endl;
1965
1966 std::cout << "phi = " << std::endl;
1967 for (int i = 0; i < totnpts; ++i)
1968 {
1969 std::cout << Jphi[i] << ", ";
1970 }
1971 std::cout << std::endl << std::endl;
1972
1973 std::cout << "J = " << std::endl;
1974 for (int i = 0; i < totnpts; ++i)
1975 {
1976 std::cout << Jcurrent[i] << ", ";
1977 }
1978 std::cout << std::endl << std::endl;
1979}
1980
1982 const int time, const Array<OneD, const Array<OneD, NekDouble>> &fields)
1983{
1984 int nq = m_fields[0]->GetTotPoints();
1985 int nTraceNumPoints = GetTraceTotPoints();
1986
1987 Array<OneD, NekDouble> outfield(nTraceNumPoints, 0.0);
1988
1989 switch (m_PolType)
1990 {
1991 // (n \times H^r)_z = H1r (n \times e^1)_z + H2r (n \times e^2)_z,
1993 {
1994 Array<OneD, NekDouble> tmp(nq);
1995 Array<OneD, NekDouble> tmpFwd(nTraceNumPoints);
1996
1997 for (int i = 0; i < 2; i++)
1998 {
1999 tmp = GetIncidentField(i, time);
2000 Vmath::Vadd(nq, fields[i], 1, tmp, 1, tmp, 1);
2001
2002 m_fields[0]->ExtractTracePhys(tmp, tmpFwd);
2003 Vmath::Vvtvp(nTraceNumPoints, &m_ntimesMFFwd[i][2][0], 1,
2004 &tmpFwd[0], 1, &outfield[0], 1, &outfield[0], 1);
2005 }
2006 }
2007 break;
2008
2010 {
2011 Array<OneD, NekDouble> tmp(nq);
2012
2013 tmp = GetIncidentField(2, time);
2014 Vmath::Vadd(nq, fields[2], 1, tmp, 1, tmp, 1);
2015 m_fields[0]->ExtractTracePhys(tmp, outfield);
2016 }
2017 break;
2018
2019 default:
2020 break;
2021 }
2022
2023 return outfield;
2024}
2025
2027 const NekDouble PMLstart,
2028 const NekDouble PMLmaxsigma,
2029 Array<OneD, Array<OneD, NekDouble>> &SigmaPML)
2030{
2031 int nq = m_fields[0]->GetNpoints();
2032
2033 // Construct sigmaX and sigmaY for UPML
2037
2038 m_fields[0]->GetCoords(x, y, z);
2039
2040 // Construction of SigmaPML
2042 for (int j = 0; j < m_shapedim; j++)
2043 {
2044 SigmaPML[j] = Array<OneD, NekDouble>(nq, 0.0);
2045 }
2046
2047 // PML region indicator: [ 0 : curvedPML : RecPML]
2048 // RecPML = [0 : 0 : 1]
2049 // PMLRegion = [0 : 1 : 1], CurvedPML = PMLRegion - RecPML = [0: 1: 0]
2050 Array<OneD, NekDouble> RecPML(nq);
2051 Array<OneD, NekDouble> CurvedPML(nq);
2052 Array<OneD, NekDouble> PMLRegion(nq);
2053 m_fields[0]->GenerateElementVector(m_RecPML, 0.0, 1.0, RecPML);
2054 m_fields[0]->GenerateElementVector(m_PMLelement, 0.0, 1.0, PMLRegion);
2055 Vmath::Vsub(nq, PMLRegion, 1, RecPML, 1, CurvedPML, 1);
2056
2057 switch (m_AddPML)
2058 {
2059 // RecPML only
2060 case 1:
2061 {
2062 // Rectangular PML
2063 NekDouble xRlayer, xLlayer, yRlayer, yLlayer;
2064
2065 xRlayer = Vmath::Vmax(nq, x, 1) - PMLthickness;
2066 xLlayer = Vmath::Vmin(nq, x, 1) + PMLthickness;
2067 yRlayer = Vmath::Vmax(nq, y, 1) - PMLthickness;
2068 yLlayer = Vmath::Vmin(nq, y, 1) + PMLthickness;
2069
2070 NekDouble xd, yd;
2071 for (int i = 0; i < nq; i++)
2072 {
2073 // SimgaPML along e^1
2074 if (x[i] >= xRlayer)
2075 {
2076 xd = (x[i] - xRlayer) / PMLthickness;
2077 }
2078
2079 else if (x[i] <= xLlayer)
2080 {
2081 xd = (xLlayer - x[i]) / PMLthickness;
2082 }
2083
2084 else
2085 {
2086 xd = 0.0;
2087 }
2088
2089 SigmaPML[0][i] = RecPML[i] * PMLmaxsigma * (xd * xd * xd);
2090
2091 // SigmaPML along e^2
2092 if (y[i] >= yRlayer)
2093 {
2094 yd = (y[i] - yRlayer) / PMLthickness;
2095 }
2096
2097 else if (y[i] <= yLlayer)
2098 {
2099 yd = (yLlayer - y[i]) / PMLthickness;
2100 }
2101
2102 else
2103 {
2104 yd = 0.0;
2105 }
2106
2107 SigmaPML[1][i] = PMLRegion[i] * PMLmaxsigma * (yd * yd * yd);
2108 }
2109 }
2110 break;
2111
2112 // CurvedPML only
2113 case 2:
2114 {
2115 // Curved PML
2116 NekDouble relrad, rad;
2117 for (int i = 0; i < nq; i++)
2118 {
2119 rad = sqrt(x[i] * x[i] / m_MMFfactors[0] / m_MMFfactors[0] +
2120 y[i] * y[i] / m_MMFfactors[1] / m_MMFfactors[1]);
2121
2122 if (rad >= PMLstart)
2123 {
2124 relrad = (rad - PMLstart) / PMLthickness;
2125 SigmaPML[1][i] =
2126 PMLRegion[i] * PMLmaxsigma * pow(relrad, m_PMLorder);
2127 }
2128 }
2129 }
2130 break;
2131
2132 // Slanted PML
2133 case 3:
2134 {
2135 NekDouble relrad, radon, radtw, radth, radfo;
2136 for (int i = 0; i < nq; i++)
2137 {
2138 radon = -1.0 * x[i] + y[i] - 7;
2139 radtw = x[i] + y[i] - 7;
2140 radth = -x[i] - y[i] - 7;
2141 radfo = x[i] - y[i] - 7;
2142
2143 if (radon >= 0.0)
2144 {
2145 relrad = radon / PMLthickness;
2146 SigmaPML[1][i] =
2147 PMLRegion[i] * PMLmaxsigma * pow(relrad, m_PMLorder);
2148 }
2149
2150 if (radtw >= 0.0)
2151 {
2152 relrad = radtw / PMLthickness;
2153 SigmaPML[0][i] =
2154 PMLRegion[i] * PMLmaxsigma * pow(relrad, m_PMLorder);
2155 }
2156
2157 if (radth >= 0.0)
2158 {
2159 relrad = radth / PMLthickness;
2160 SigmaPML[0][i] =
2161 PMLRegion[i] * PMLmaxsigma * pow(relrad, m_PMLorder);
2162 }
2163
2164 if (radfo >= 0.0)
2165 {
2166 relrad = radfo / PMLthickness;
2167 SigmaPML[1][i] =
2168 PMLRegion[i] * PMLmaxsigma * pow(relrad, m_PMLorder);
2169 }
2170 }
2171 }
2172 break;
2173 }
2174
2175 std::cout << "*** sigma1 = [ " << Vmath::Vmin(nq, &SigmaPML[0][0], 1)
2176 << " , " << Vmath::Vmax(nq, &SigmaPML[0][0], 1)
2177 << " ] , sigma2 = [ " << Vmath::Vmin(nq, &SigmaPML[1][0], 1)
2178 << " , " << Vmath::Vmax(nq, &SigmaPML[1][0], 1) << " ] "
2179 << std::endl;
2180}
2181
2184{
2185 int nq = GetTotPoints();
2186 NekDouble energy;
2187
2188 Array<OneD, NekDouble> tmp(nq, 0.0);
2189
2190 for (int i = 0; i < 3; ++i)
2191 {
2192 Vmath::Vvtvp(nq, &fields[i][0], 1, &fields[i][0], 1, &tmp[0], 1,
2193 &tmp[0], 1);
2194 }
2195
2196 energy = 0.5 * (m_fields[0]->Integral(tmp));
2197 return energy;
2198}
2199
2203{
2204 switch (m_TestMaxwellType)
2205 {
2207 {
2208 m_fields[0]->GenerateElementVector(m_ElemtGroup1, m_varepsilon[0],
2209 m_varepsilon[1], epsvec[0]);
2210 m_fields[0]->GenerateElementVector(m_ElemtGroup1, 1.0, 1.0,
2211 muvec[0]);
2212 }
2213 break;
2214
2220 {
2221 switch (m_PolType)
2222 {
2224 {
2225 m_fields[0]->GenerateElementVector(m_ElemtGroup1, m_mu[0],
2226 1.0, muvec[0]);
2227 m_fields[0]->GenerateElementVector(m_ElemtGroup1, m_mu[1],
2228 1.0, muvec[1]);
2229 m_fields[0]->GenerateElementVector(
2230 m_ElemtGroup1, m_varepsilon[2], 1.0, epsvec[2]);
2231
2232 // // ONLY FOR VARIABLE ANISOTROPY TEST
2233 // int nq = GetTotPoints();
2234
2235 // Array<OneD, NekDouble> tmpIN(nq);
2236
2237 // m_fields[0]->GenerateElementVector(m_ElemtGroup1, 1.0,
2238 // 0.0, tmpIN);
2239
2240 // Array<OneD, NekDouble> x0(nq);
2241 // Array<OneD, NekDouble> x1(nq);
2242 // Array<OneD, NekDouble> x2(nq);
2243
2244 // m_fields[0]->GetCoords(x0,x1,x2);
2245
2246 // for (int i=0; i<nq; i++)
2247 // {
2248 // muvec[1][i] = tmpIN[i]*(1.0 - 2*x0[i]*x0[i]) +
2249 // (1.0-tmpIN[i]);
2250 // }
2251 }
2252 break;
2253
2255 {
2256 m_fields[0]->GenerateElementVector(
2257 m_ElemtGroup1, m_varepsilon[0], 1.0, epsvec[0]);
2258 m_fields[0]->GenerateElementVector(
2259 m_ElemtGroup1, m_varepsilon[1], 1.0, epsvec[1]);
2260 m_fields[0]->GenerateElementVector(m_ElemtGroup1, m_mu[2],
2261 1.0, muvec[2]);
2262
2263 // // ONLY FOR VARIABLE ANISOTROPY TEST
2264 // int nq = GetTotPoints();
2265
2266 // Array<OneD, NekDouble> tmpIN(nq);
2267
2268 // m_fields[0]->GenerateElementVector(m_ElemtGroup1, 1.0,
2269 // 0.0, tmpIN);
2270
2271 // Array<OneD, NekDouble> x0(nq);
2272 // Array<OneD, NekDouble> x1(nq);
2273 // Array<OneD, NekDouble> x2(nq);
2274
2275 // m_fields[0]->GetCoords(x0,x1,x2);
2276
2277 // for (int i=0; i<nq; i++)
2278 // {
2279 // epsvec[1][i] = tmpIN[i]*(1.0 - 2*x0[i]*x0[i]) +
2280 // (1.0-tmpIN[i]);
2281 // }
2282 }
2283 break;
2284
2285 default:
2286 break; // Pol
2287 }
2288 }
2289
2290 default:
2291 break; // TestType
2292 }
2293}
2294
2296 const Array<OneD, const NekDouble> &radvec,
2298 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &muvec,
2299 [[maybe_unused]] const bool Dispersion)
2300{
2301 int nq = GetNpoints();
2302
2303 // Cloaking metamaterial
2304 // \varepsilon_\theta = (b/(b-a))^2
2305 // \varepsilon_r = (b/(b-a))^2 ((r-a)/r)^2
2306 // \mu_z = 1.0m_CloakingOn
2307
2308 NekDouble m_b = 1.0 / 0.314;
2309 NekDouble m_a = 1.0;
2310
2311 NekDouble m_adel = m_a - m_Cloakraddelta;
2312
2313 NekDouble boveradel = m_b / (m_b - m_adel);
2314
2315 Array<OneD, NekDouble> Cloakregion(nq, 0.0);
2316
2317 NekDouble la = m_MMFfactors[0];
2318 NekDouble lb = m_MMFfactors[1];
2319
2320 NekDouble ExactCloakArea;
2321 if (fabs(la * lb - 1.0) < 0.00001)
2322 {
2323 ExactCloakArea = m_pi * (m_b * m_b - m_a * m_a);
2324 }
2325
2326 else
2327 {
2328 ExactCloakArea = m_pi * (3.0 * lb * 3.0 * la - lb * la);
2329 }
2330
2331 m_fields[0]->GenerateElementVector(m_ElemtGroup1, 1.0, 0.0, Cloakregion);
2332
2333 ExactCloakArea = ExactCloakArea - (m_fields[0]->Integral(Cloakregion));
2334 std::cout << "*** Error of Cloakregion area = " << ExactCloakArea
2335 << std::endl;
2336
2337 NekDouble ratio;
2338
2339 epsvec[0] = Array<OneD, NekDouble>(nq, 1.0);
2340 epsvec[1] = Array<OneD, NekDouble>(nq, 1.0);
2341 m_wp2 = Array<OneD, NekDouble>(nq, 0.0);
2342 for (int i = 0; i < nq; ++i)
2343 {
2344 if (Cloakregion[i] > 0)
2345 {
2346 // relrad = m_a +
2347 // (m_b-m_adel)*(radvec[i]-m_adel)/(Cloakradmax-m_adel);
2348 ratio = (radvec[i] - m_adel) / radvec[i];
2349
2350 epsvec[0][i] = boveradel * boveradel;
2352 {
2353 epsvec[1][i] = 1.0;
2354 m_wp2[i] = m_Incfreq * m_Incfreq *
2355 (1.0 - boveradel * boveradel * ratio * ratio) +
2356 m_wp2Tol;
2357 }
2358
2359 else
2360 {
2361 epsvec[1][i] = boveradel * boveradel * (ratio * ratio);
2362 }
2363 }
2364 }
2365}
2366
2368 const Array<OneD, const NekDouble> &radvec,
2371{
2372 int nq = GetNpoints();
2373
2374 NekDouble m_b = 2.67;
2375 NekDouble m_a = 1.33;
2376 NekDouble m_adel;
2377
2378 m_adel = m_a - m_Cloakraddelta;
2379
2380 Array<OneD, NekDouble> Cloakregion(nq, 0.0);
2381 NekDouble ExactCloakArea = m_pi * (m_b * m_b - m_a * m_a);
2382 m_fields[0]->GenerateElementVector(m_ElemtGroup1, 1.0, 0.0, Cloakregion);
2383
2384 if (m_ElemtGroup0 > 0)
2385 {
2386 Array<OneD, NekDouble> Vacregion(nq, 0.0);
2387 m_fields[0]->GenerateElementVector(m_ElemtGroup0, 1.0, 0.0, Vacregion);
2388
2389 Vmath::Vsub(nq, Cloakregion, 1, Vacregion, 1, Cloakregion, 1);
2390 }
2391
2392 ExactCloakArea = ExactCloakArea - (m_fields[0]->Integral(Cloakregion));
2393 std::cout << "*** Error of Cloakregion area = " << ExactCloakArea
2394 << std::endl;
2395
2396 epsvec[0] = Array<OneD, NekDouble>(nq, 1.0);
2397 epsvec[1] = Array<OneD, NekDouble>(nq, 1.0);
2398
2399 muvec[0] = Array<OneD, NekDouble>(nq, 1.0);
2400 muvec[1] = Array<OneD, NekDouble>(nq, 1.0);
2401 for (int i = 0; i < nq; ++i)
2402 {
2403 if (Cloakregion[i] > 0)
2404 {
2405 // relrad = m_a +
2406 // (m_b-m_a)*(radvec[i]-Cloakradmin)/(Cloakradmax-Cloakradmin);
2407 // ratio = (relrad - m_a + m_Cloakraddelta)/relrad;
2408
2409 epsvec[0][i] = radvec[i] / (radvec[i] - m_adel);
2410 epsvec[1][i] = (radvec[i] - m_adel) / radvec[i];
2411 muvec[2][i] = (m_b / (m_b - m_adel)) * (m_b / (m_b - m_adel)) *
2412 (radvec[i] - m_adel) / radvec[i];
2413
2414 muvec[0][i] = epsvec[0][i];
2415 muvec[1][i] = epsvec[1][i];
2416 epsvec[2][i] = muvec[2][i];
2417 }
2418 }
2419}
2420
2422 const Array<OneD, const Array<OneD, NekDouble>> &physarray,
2423 Array<OneD, Array<OneD, NekDouble>> &outarray)
2424{
2425 int nq = m_fields[0]->GetTotPoints();
2426 Array<OneD, NekDouble> tmp(nq);
2427
2428 Array<OneD, NekDouble> Sigma0plus1Neg(nq);
2429 Array<OneD, NekDouble> Sigma0minus1(nq);
2430 Array<OneD, NekDouble> Sigma1minus0(nq);
2431
2432 Vmath::Vsub(nq, &m_SigmaPML[1][0], 1, &m_SigmaPML[0][0], 1,
2433 &Sigma1minus0[0], 1);
2434 Vmath::Vsub(nq, &m_SigmaPML[0][0], 1, &m_SigmaPML[1][0], 1,
2435 &Sigma0minus1[0], 1);
2436 Vmath::Vadd(nq, &m_SigmaPML[0][0], 1, &m_SigmaPML[1][0], 1,
2437 &Sigma0plus1Neg[0], 1);
2438 Vmath::Neg(nq, Sigma0plus1Neg, 1);
2439
2440 switch (m_PolType)
2441 {
2443 {
2444 int indxH0 = 0;
2445 int indxH1 = 1;
2446 int indxE2 = 2;
2447 int indxQ0 = 3;
2448 int indxQ1 = 4;
2449 int indxP2 = 5;
2450
2451 // dH0/dt: Add (sigma_0 - \sigma_1) H0 + Q0
2452 Vmath::Vvtvp(nq, &Sigma0minus1[0], 1, &physarray[indxH0][0], 1,
2453 &outarray[indxH0][0], 1, &outarray[indxH0][0], 1);
2454 Vmath::Vadd(nq, &physarray[indxQ0][0], 1, &outarray[indxH0][0], 1,
2455 &outarray[indxH0][0], 1);
2456
2457 // dH1/dt: Add (sigma_1 - \sigma_0) H1 + Q1
2458 Vmath::Vvtvp(nq, &Sigma1minus0[0], 1, &physarray[indxH1][0], 1,
2459 &outarray[indxH1][0], 1, &outarray[indxH1][0], 1);
2460 Vmath::Vadd(nq, &physarray[indxQ1][0], 1, &outarray[indxH1][0], 1,
2461 &outarray[indxH1][0], 1);
2462
2463 // dHz/dt: Add -(\sigma_0 + \sigma_1) Ez + Pz
2464 Vmath::Vvtvp(nq, &Sigma0plus1Neg[0], 1, &physarray[indxE2][0], 1,
2465 &outarray[indxE2][0], 1, &outarray[indxE2][0], 1);
2466 Vmath::Vadd(nq, &physarray[indxP2][0], 1, &outarray[indxE2][0], 1,
2467 &outarray[indxE2][0], 1);
2468
2469 // dQ0/dt: Assign -\sigma_0 * ( Q0 + (\sigma_0 - \sigma_1) * H0 )
2470 Vmath::Vvtvp(nq, &Sigma0minus1[0], 1, &physarray[indxH0][0], 1,
2471 &physarray[indxQ0][0], 1, &outarray[indxQ0][0], 1);
2472 Vmath::Vmul(nq, &m_SigmaPML[0][0], 1, &outarray[indxQ0][0], 1,
2473 &outarray[indxQ0][0], 1);
2474 Vmath::Neg(nq, &outarray[indxQ0][0], 1);
2475
2476 // dQ1/dt: Assign -\sigma_1 * ( Q1 + (\sigma_1 - \sigma_0) * H1 )
2477 Vmath::Vvtvp(nq, &Sigma1minus0[0], 1, &physarray[indxH1][0], 1,
2478 &physarray[indxQ1][0], 1, &outarray[indxQ1][0], 1);
2479 Vmath::Vmul(nq, &m_SigmaPML[1][0], 1, &outarray[indxQ1][0], 1,
2480 &outarray[indxQ1][0], 1);
2481 Vmath::Neg(nq, &outarray[indxQ1][0], 1);
2482
2484 {
2485 Vmath::Vvtvp(nq, &m_wp2[0], 1, &physarray[indxH1][0], 1,
2486 &outarray[indxQ1][0], 1, &outarray[indxQ1][0], 1);
2487 }
2488
2489 // dP3/dt: Assign - \sigma_1 * \sigma_2 * E_z
2490 Vmath::Vmul(nq, &m_SigmaPML[0][0], 1, &m_SigmaPML[1][0], 1,
2491 &outarray[indxP2][0], 1);
2492 Vmath::Vmul(nq, &physarray[indxE2][0], 1, &outarray[indxP2][0], 1,
2493 &outarray[indxP2][0], 1);
2494 Vmath::Neg(nq, &outarray[indxP2][0], 1);
2495 }
2496 break;
2497
2499 {
2500 int indxE0 = 0;
2501 int indxE1 = 1;
2502 int indxH2 = 2;
2503 int indxQ0 = 3;
2504 int indxQ1 = 4;
2505 int indxP2 = 5;
2506
2507 // dE0/dt: Add (sigma_0 - \sigma_1) E0 - Q0
2508 Vmath::Vvtvp(nq, &Sigma0minus1[0], 1, &physarray[indxE0][0], 1,
2509 &outarray[indxE0][0], 1, &outarray[indxE0][0], 1);
2510 Vmath::Vsub(nq, &outarray[indxE0][0], 1, &physarray[indxQ0][0], 1,
2511 &outarray[indxE0][0], 1);
2512
2513 // dE1/dt: Add (sigma_1 - \sigma_0) E1 - Q1
2514 Vmath::Vvtvp(nq, &Sigma1minus0[0], 1, &physarray[indxE1][0], 1,
2515 &outarray[indxE1][0], 1, &outarray[indxE1][0], 1);
2516 Vmath::Vsub(nq, &outarray[indxE1][0], 1, &physarray[indxQ1][0], 1,
2517 &outarray[indxE1][0], 1);
2518
2519 // dHz/dt: Add -(\sigma_0 + \sigma_1) Hz - Pz
2520 Vmath::Vvtvp(nq, &Sigma0plus1Neg[0], 1, &physarray[indxH2][0], 1,
2521 &outarray[indxH2][0], 1, &outarray[indxH2][0], 1);
2522 Vmath::Vsub(nq, &outarray[indxH2][0], 1, &physarray[indxP2][0], 1,
2523 &outarray[indxH2][0], 1);
2524
2525 // dQ0/dt: Assign -\sigma_0 * ( Q0 + (\sigma_1 - \sigma_0) * E0 )
2526 Vmath::Vvtvp(nq, &Sigma1minus0[0], 1, &physarray[indxE0][0], 1,
2527 &physarray[indxQ0][0], 1, &outarray[indxQ0][0], 1);
2528 Vmath::Vmul(nq, &m_SigmaPML[0][0], 1, &outarray[indxQ0][0], 1,
2529 &outarray[indxQ0][0], 1);
2530 Vmath::Neg(nq, &outarray[indxQ0][0], 1);
2531
2532 // dQ1/dt: Assign -\sigma_1 * ( Q1 + (\sigma_0 - \sigma_1) * E1 )
2533 Vmath::Vvtvp(nq, &Sigma0minus1[0], 1, &physarray[indxE1][0], 1,
2534 &physarray[indxQ1][0], 1, &outarray[indxQ1][0], 1);
2535 Vmath::Vmul(nq, &m_SigmaPML[1][0], 1, &outarray[indxQ1][0], 1,
2536 &outarray[indxQ1][0], 1);
2537 Vmath::Neg(nq, &outarray[indxQ1][0], 1);
2538
2540 {
2541 Vmath::Vvtvp(nq, &m_wp2[0], 1, &physarray[indxE1][0], 1,
2542 &outarray[indxQ1][0], 1, &outarray[indxQ1][0], 1);
2543 }
2544
2545 // dP3/dt: Assign \sigma_1 * \sigma_2 * H_z
2546 Vmath::Vmul(nq, &m_SigmaPML[0][0], 1, &m_SigmaPML[1][0], 1,
2547 &outarray[indxP2][0], 1);
2548 Vmath::Vmul(nq, &physarray[indxH2][0], 1, &outarray[indxP2][0], 1,
2549 &outarray[indxP2][0], 1);
2550 }
2551 break;
2552
2553 default:
2554 break;
2555 }
2556}
2557
2559 const int n, const NekDouble time,
2560 const Array<OneD, const Array<OneD, NekDouble>> &fieldphys)
2561{
2562 int nvar = m_fields.size();
2563 int nq = m_fields[0]->GetTotPoints();
2564 int ncoeffs = m_fields[0]->GetNcoeffs();
2565
2566 std::string outname = m_sessionName + "Tot_" + std::to_string(n) + ".chk";
2567
2568 std::vector<std::string> variables(nvar);
2569 std::vector<Array<OneD, NekDouble>> fieldcoeffs(nvar);
2570
2571 for (int i = 0; i < nvar; ++i)
2572 {
2573 fieldcoeffs[i] = Array<OneD, NekDouble>(ncoeffs);
2574 }
2575
2576 Array<OneD, NekDouble> totfield(nq);
2577 for (int i = 0; i < nvar; ++i)
2578 {
2579 totfield = GetIncidentField(i, time);
2580 Vmath::Vadd(nq, fieldphys[i], 1, totfield, 1, totfield, 1);
2581
2582 m_fields[i]->FwdTrans(totfield, fieldcoeffs[i]);
2583 variables[i] = m_boundaryConditions->GetVariable(i);
2584 }
2585
2586 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
2587}
2588
2589// Only for nvar = 3
2591 const int n, const Array<OneD, const Array<OneD, NekDouble>> &fieldphys)
2592{
2593 int nvar = m_fields.size();
2594 int nq = m_fields[0]->GetTotPoints();
2595 int ncoeffs = m_fields[0]->GetNcoeffs();
2596
2597 std::string outname = m_sessionName + "Plot_" + std::to_string(n) + ".chk";
2598
2599 std::vector<std::string> variables(nvar);
2600 variables[0] = "Fx";
2601 variables[1] = "Fy";
2602 variables[2] = "Fz";
2603
2604 std::vector<Array<OneD, NekDouble>> fieldcoeffs(nvar);
2605 for (int i = 0; i < nvar; ++i)
2606 {
2607 fieldcoeffs[i] = Array<OneD, NekDouble>(ncoeffs);
2608 }
2609
2610 Array<OneD, NekDouble> tmp(nq);
2611 for (int k = 0; k < m_spacedim; ++k)
2612 {
2613 Vmath::Vmul(nq, &fieldphys[0][0], 1, &m_movingframes[0][k * nq], 1,
2614 &tmp[0], 1);
2615 Vmath::Vvtvp(nq, &fieldphys[1][0], 1, &m_movingframes[1][k * nq], 1,
2616 &tmp[0], 1, &tmp[0], 1);
2617
2618 m_fields[k]->FwdTrans(tmp, fieldcoeffs[k]);
2619 }
2620
2621 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
2622}
2623
2625 const int n, const NekDouble time,
2626 const Array<OneD, const Array<OneD, NekDouble>> &fieldphys)
2627{
2628 int nvar = m_fields.size();
2629 int nq = m_fields[0]->GetTotPoints();
2630 int ncoeffs = m_fields[0]->GetNcoeffs();
2631
2632 std::string outname =
2633 m_sessionName + "TotPlot_" + std::to_string(n) + ".chk";
2634
2635 std::vector<std::string> variables(nvar);
2636 variables[0] = "Frx";
2637 variables[1] = "Fry";
2638 variables[2] = "Frz";
2639 for (int i = 3; i < nvar; ++i)
2640 {
2641 variables[i] = m_boundaryConditions->GetVariable(i);
2642 }
2643
2644 std::vector<Array<OneD, NekDouble>> fieldcoeffs(nvar);
2645 for (int i = 0; i < nvar; ++i)
2646 {
2647 fieldcoeffs[i] = Array<OneD, NekDouble>(ncoeffs);
2648 }
2649
2650 Array<OneD, NekDouble> tmp(nq);
2651 Array<OneD, NekDouble> totfield0(nq);
2652 Array<OneD, NekDouble> totfield1(nq);
2653
2654 totfield0 = GetIncidentField(0, time);
2655 Vmath::Vadd(nq, fieldphys[0], 1, totfield0, 1, totfield0, 1);
2656
2657 totfield1 = GetIncidentField(1, time);
2658 Vmath::Vadd(nq, fieldphys[1], 1, totfield1, 1, totfield1, 1);
2659
2660 for (int k = 0; k < m_spacedim; ++k)
2661 {
2662 Vmath::Vmul(nq, &totfield0[0], 1, &m_movingframes[0][k * nq], 1,
2663 &tmp[0], 1);
2664 Vmath::Vvtvp(nq, &totfield1[0], 1, &m_movingframes[1][k * nq], 1,
2665 &tmp[0], 1, &tmp[0], 1);
2666
2667 m_fields[k]->FwdTrans(tmp, fieldcoeffs[k]);
2668 }
2669
2670 for (int j = 3; j < nvar; ++j)
2671 {
2672 m_fields[j]->FwdTrans(fieldphys[j], fieldcoeffs[j]);
2673 }
2674
2675 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
2676}
2677
2679 const int n, [[maybe_unused]] const NekDouble time,
2680 const Array<OneD, const Array<OneD, NekDouble>> &fieldphys)
2681{
2682 int nvar = m_fields.size();
2683 int nq = m_fields[0]->GetTotPoints();
2684 int ncoeffs = m_fields[0]->GetNcoeffs();
2685
2686 std::string outname =
2687 m_sessionName + "EDFlux_" + std::to_string(n) + ".chk";
2688
2689 std::vector<std::string> variables(nvar);
2690 variables[0] = "EDFx";
2691 variables[1] = "EDFy";
2692 variables[2] = "EDFz";
2693 for (int i = 3; i < nvar; ++i)
2694 {
2695 variables[i] = m_boundaryConditions->GetVariable(i);
2696 }
2697
2698 std::vector<Array<OneD, NekDouble>> fieldcoeffs(nvar);
2699 for (int i = 0; i < nvar; ++i)
2700 {
2701 fieldcoeffs[i] = Array<OneD, NekDouble>(ncoeffs);
2702 }
2703
2704 Array<OneD, NekDouble> tmp(nq);
2705
2706 // TE: H^3 (E^2 e^1 - E^1 e^2 )
2707 // TM: -E^3 (H^2 e^1 - H^1 e^2 )
2708 for (int k = 0; k < m_spacedim; ++k)
2709 {
2710 Vmath::Vmul(nq, &fieldphys[0][0], 1, &m_movingframes[1][k * nq], 1,
2711 &tmp[0], 1);
2712 Vmath::Vvtvm(nq, &fieldphys[1][0], 1, &m_movingframes[0][k * nq], 1,
2713 &tmp[0], 1, &tmp[0], 1);
2714
2715 Vmath::Vmul(nq, &fieldphys[2][0], 1, &tmp[0], 1, &tmp[0], 1);
2716
2718 {
2719 Vmath::Neg(nq, tmp, 1);
2720 }
2721
2722 m_fields[k]->FwdTrans(tmp, fieldcoeffs[k]);
2723 }
2724
2725 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
2726}
2727
2729 const int n, [[maybe_unused]] const NekDouble time,
2730 const Array<OneD, const Array<OneD, NekDouble>> &fieldphys)
2731{
2732 int nvar = m_fields.size();
2733 int nq = m_fields[0]->GetTotPoints();
2734 int ncoeffs = m_fields[0]->GetNcoeffs();
2735
2736 std::string outname =
2737 m_sessionName + "Energy_" + std::to_string(n) + ".chk";
2738
2739 std::vector<std::string> variables(nvar);
2740 variables[0] = "Energy";
2741 variables[1] = "EnergyFlux";
2742 variables[2] = "Zero";
2743 for (int i = 3; i < nvar; ++i)
2744 {
2745 variables[i] = m_boundaryConditions->GetVariable(i);
2746 }
2747
2748 std::vector<Array<OneD, NekDouble>> fieldcoeffs(nvar);
2749 for (int i = 0; i < nvar; ++i)
2750 {
2751 fieldcoeffs[i] = Array<OneD, NekDouble>(ncoeffs);
2752 }
2753
2754 // Energy = 0.5 * ( E^2 + H^2 )
2755 Array<OneD, NekDouble> energy(nq, 0.0);
2756 Array<OneD, NekDouble> totfield(nq);
2757 for (int k = 0; k < m_spacedim; ++k)
2758 {
2759 // totfield = GetIncidentField(k,time);
2760 // Vmath::Vadd(nq, &fieldphys[k][0], 1, &totfield[0], 1, &totfield[0],
2761 // 1);
2762
2763 Vmath::Vvtvp(nq, &fieldphys[k][0], 1, &fieldphys[k][0], 1, &energy[0],
2764 1, &energy[0], 1);
2765 }
2766 Vmath::Smul(nq, 0.5, energy, 1, energy, 1);
2767 m_fields[0]->FwdTrans(energy, fieldcoeffs[0]);
2768
2769 // EnergyFlux = F3* sqrt( F1^2 + F2^2 )
2770 Array<OneD, NekDouble> energyflux(nq, 0.0);
2772 for (int k = 0; k < 2; ++k)
2773 {
2774 // totfield = GetIncidentField(k,time);
2775 // Vmath::Vadd(nq, &fieldphys[k][0], 1, &totfield[0], 1, &totfield[0],
2776 // 1);
2777
2778 Vmath::Vvtvp(nq, &fieldphys[k][0], 1, &fieldphys[k][0], 1,
2779 &energyflux[0], 1, &energyflux[0], 1);
2780 }
2781
2782 Vmath::Vsqrt(nq, energyflux, 1, energyflux, 1);
2783 Vmath::Vmul(nq, &fieldphys[2][0], 1, &energyflux[0], 1, &energyflux[0], 1);
2784
2785 m_fields[1]->FwdTrans(energyflux, fieldcoeffs[1]);
2786 m_fields[2]->FwdTrans(Zero, fieldcoeffs[2]);
2787
2788 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
2789}
2790
2792 const NekDouble Psx,
2793 const NekDouble Psy,
2794 const NekDouble Psz,
2795 const NekDouble Gaussianradius)
2796{
2797 int nq = m_fields[0]->GetTotPoints();
2798 int ncoeffs = m_fields[0]->GetNcoeffs();
2799
2803
2804 m_fields[0]->GetCoords(x, y, z);
2805
2806 Array<OneD, NekDouble> outarray(nq, 0.0);
2807 Array<OneD, NekDouble> tmpc(ncoeffs);
2808 NekDouble rad;
2809
2810 NekDouble SFradius = m_PSduration * 0.1;
2811 NekDouble SmoothFactor =
2812 1.0 / (1.0 + exp(-0.5 * (time - m_PSduration) / SFradius));
2813
2814 for (int j = 0; j < nq; ++j)
2815 {
2816 rad = sqrt((x[j] - Psx) * (x[j] - Psx) + (y[j] - Psy) * (y[j] - Psy) +
2817 (z[j] - Psz) * (z[j] - Psz));
2818 outarray[j] = SmoothFactor * exp(-1.0 * (rad / Gaussianradius) *
2819 (rad / Gaussianradius));
2820 }
2821
2822 m_fields[0]->FwdTransLocalElmt(outarray, tmpc);
2823 m_fields[0]->BwdTrans(tmpc, outarray);
2824
2825 return outarray;
2826}
2827
2829{
2830 int nq = GetTotPoints();
2831
2832 NekDouble m_Omega = 1.5486 * 0.000001;
2833
2834 NekDouble x0j, x1j, x2j;
2835 NekDouble sin_theta, cos_theta, sin_varphi, cos_varphi;
2836
2840
2841 m_fields[0]->GetCoords(x, y, z);
2842
2843 Array<OneD, NekDouble> outarray(nq, 0.0);
2844 for (int j = 0; j < nq; ++j)
2845 {
2846 x0j = x[j];
2847 x1j = y[j];
2848 x2j = z[j];
2849
2850 CartesianToSpherical(x0j, x1j, x2j, sin_varphi, cos_varphi, sin_theta,
2851 cos_theta);
2852
2853 outarray[j] = 2.0 * m_Omega * sin_theta;
2854 }
2855
2856 return outarray;
2857}
2858
2860 Array<OneD, Array<OneD, NekDouble>> &outarray)
2861{
2862 int nq = physarray[0].size();
2863
2864 Array<OneD, NekDouble> tmp(nq);
2865
2866 int indx;
2867 for (int j = 0; j < m_shapedim; ++j)
2868 {
2869 if (j == 0)
2870 {
2871 indx = 2;
2872 }
2873
2874 else
2875 {
2876 indx = 1;
2877 }
2878
2879 Vmath::Vmul(nq, m_coriolis, 1, physarray[indx], 1, tmp, 1);
2880
2881 switch (m_PolType)
2882 {
2884 {
2885 Vmath::Vmul(nq, m_muvec[indx], 1, tmp, 1, tmp, 1);
2886 }
2887 break;
2888
2890 {
2891 Vmath::Vmul(nq, m_epsvec[indx], 1, tmp, 1, tmp, 1);
2892 }
2893 break;
2894
2895 default:
2896 break;
2897 }
2898
2899 if (j == 1)
2900 {
2901 Vmath::Neg(nq, tmp, 1);
2902 }
2903
2904 Vmath::Vadd(nq, tmp, 1, outarray[j], 1, outarray[j], 1);
2905 }
2906}
2907
2909{
2910 int nq = GetNpoints();
2911
2912 NekDouble m_b = 1.0 / 0.314;
2913 NekDouble m_a = 1.0;
2914
2915 Array<OneD, int> Layer(CloakNlayer);
2916
2917 NekDouble la = m_MMFfactors[0];
2918 NekDouble lb = m_MMFfactors[1];
2919 if (CloakNlayer == 8)
2920 {
2921 // Circular 8 layer
2922 if (fabs(la * lb - 1.0) < 0.0001)
2923 {
2924 Layer[0] = 119;
2925 Layer[1] = 239;
2926 Layer[2] = 323;
2927 Layer[3] = 459;
2928 Layer[4] = 575;
2929 Layer[5] = 727;
2930 Layer[6] = 891;
2931 Layer[7] = 1059;
2932 }
2933
2934 // Ellipsoid 8 layer
2935 else
2936 {
2937 Layer[0] = 115;
2938 Layer[1] = 219;
2939 Layer[2] = 335;
2940 Layer[3] = 459;
2941 Layer[4] = 607;
2942 Layer[5] = 767;
2943 Layer[6] = 951;
2944 Layer[7] = 1155;
2945 }
2946 }
2947
2948 if (CloakNlayer == 16)
2949 {
2950 // Circular 16 layer
2951 if (fabs(la * lb - 1.0) < 0.0001)
2952 {
2953 Layer[0] = 43;
2954 Layer[1] = 87;
2955 Layer[2] = 135;
2956 Layer[3] = 187;
2957 Layer[4] = 239;
2958 Layer[5] = 295;
2959 Layer[6] = 355;
2960 Layer[7] = 415;
2961 Layer[8] = 479;
2962 Layer[9] = 555;
2963 Layer[10] = 639;
2964 Layer[11] = 727;
2965 Layer[12] = 823;
2966 Layer[13] = 927;
2967 Layer[14] = 1039;
2968 Layer[15] = 1159;
2969 }
2970
2971 // Ellipsoid 8 layer
2972 else
2973 {
2974 Layer[0] = 135;
2975 Layer[1] = 259;
2976 Layer[2] = 387;
2977 Layer[3] = 523;
2978 Layer[4] = 667;
2979 Layer[5] = 803;
2980 Layer[6] = 939;
2981 Layer[7] = 1083;
2982 Layer[8] = 1235;
2983 Layer[9] = 1387;
2984 Layer[10] = 1539;
2985 Layer[11] = 1699;
2986 Layer[12] = 1867;
2987 Layer[13] = 2035;
2988 Layer[14] = 2203;
2989 Layer[15] = 2379;
2990 }
2991 }
2992
2996
2997 m_fields[0]->GetCoords(x0, x1, x2);
2998
2999 Array<OneD, NekDouble> Formertmp(nq, 0.0);
3000 Array<OneD, NekDouble> Currenttmp(nq, 0.0);
3001 Array<OneD, NekDouble> Cloakregion(nq, 0.0);
3002
3003 m_fields[0]->GenerateElementVector(Layer[0], 1.0, 0.0, Currenttmp);
3004 Vmath::Vcopy(nq, Currenttmp, 1, Cloakregion, 1);
3005 for (int i = 1; i < CloakNlayer; ++i)
3006 {
3007 m_fields[0]->GenerateElementVector(Layer[i], 1.0, 0.0, Currenttmp);
3008 m_fields[0]->GenerateElementVector(Layer[i - 1], 1.0, 0.0, Formertmp);
3009
3010 Vmath::Vsub(nq, Currenttmp, 1, Formertmp, 1, Currenttmp, 1);
3011
3012 Vmath::Svtvp(nq, 1.0 * (i + 1), Currenttmp, 1, Cloakregion, 1,
3013 Cloakregion, 1);
3014 }
3015
3016 Array<OneD, NekDouble> radvec(nq);
3017
3018 for (int i = 0; i < nq; ++i)
3019 {
3020 switch (m_MMFdir)
3021 {
3023 {
3024 if ((Cloakregion[i] > 0) && (CloakNlayer > 0))
3025 {
3026 radvec[i] = 1.0 + (m_b - m_a) / CloakNlayer *
3027 (Cloakregion[i] - 0.5);
3028 }
3029
3030 else
3031 {
3032 radvec[i] =
3033 sqrt(x0[i] * x0[i] / la / la + x1[i] * x1[i] / lb / lb);
3034 }
3035 }
3036 break;
3037
3039 {
3040 radvec[i] = sqrt(2.0 * x0[i] * x0[i] +
3041 x1[i] * x1[i] * x1[i] * x1[i] + x1[i] * x1[i]);
3042 }
3043 break;
3044
3046 {
3047 radvec[i] = sqrt(3.0 * x0[i] * x0[i] +
3048 x1[i] * x1[i] * x1[i] * x1[i] - x1[i] * x1[i]);
3049 }
3050 break;
3051
3052 default:
3053 break;
3054 }
3055 }
3056
3057 return radvec;
3058}
3059
3061{
3064 s, "TestMaxwellType",
3066 SolverUtils::AddSummaryItem(s, "PolType",
3068 SolverUtils::AddSummaryItem(s, "IncType",
3070
3071 if (m_varepsilon[0] * m_varepsilon[1] * m_varepsilon[2] > 1.0)
3072 {
3073 SolverUtils::AddSummaryItem(s, "varepsilon1", m_varepsilon[0]);
3074 SolverUtils::AddSummaryItem(s, "varepsilon2", m_varepsilon[1]);
3075 SolverUtils::AddSummaryItem(s, "varepsilon3", m_varepsilon[2]);
3076 }
3077
3078 if (m_mu[0] * m_mu[1] * m_mu[2] > 1.0)
3079 {
3080 SolverUtils::AddSummaryItem(s, "mu1", m_mu[0]);
3081 SolverUtils::AddSummaryItem(s, "mu2", m_mu[1]);
3082 SolverUtils::AddSummaryItem(s, "mu3", m_mu[2]);
3083 }
3084
3085 if (m_boundaryforSF > 0)
3086 {
3088 }
3089
3090 if (m_ElemtGroup1 > 0)
3091 {
3092 SolverUtils::AddSummaryItem(s, "CloakNlayer", m_CloakNlayer);
3093 SolverUtils::AddSummaryItem(s, "ElemtGroup1", m_ElemtGroup1);
3094 }
3095
3096 SolverUtils::AddSummaryItem(s, "AddRotation", m_AddRotation);
3097
3098 if (m_AddPML > 0)
3099 {
3101 SolverUtils::AddSummaryItem(s, "PMLelement", m_PMLelement);
3104 SolverUtils::AddSummaryItem(s, "PMLthickness", m_PMLthickness);
3106 SolverUtils::AddSummaryItem(s, "PMLmaxsigma", m_PMLmaxsigma);
3107 }
3108
3109 if (m_SourceType)
3110 {
3111 SolverUtils::AddSummaryItem(s, "SourceType",
3116 SolverUtils::AddSummaryItem(s, "PSduration", m_PSduration);
3117 SolverUtils::AddSummaryItem(s, "Gaussianradius", m_Gaussianradius);
3118 }
3119
3120 if (m_CloakType)
3121 {
3123 SolverUtils::AddSummaryItem(s, "DispersiveCloak", m_DispersiveCloak);
3124 SolverUtils::AddSummaryItem(s, "CloakNlayer", m_CloakNlayer);
3125 SolverUtils::AddSummaryItem(s, "Cloakraddelta", m_Cloakraddelta);
3126 }
3127}
3129{
3130 int Ntot = inarray.size();
3131
3132 NekDouble reval = 0.0;
3133 for (int i = 0; i < Ntot; ++i)
3134 {
3135 std::cout << "[" << i << "] = " << inarray[2][i] << std::endl;
3136 // reval = reval + inarray[i]*inarray[i];
3137 }
3138 reval = sqrt(reval / Ntot);
3139}
3140} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
const char *const CloakTypeMap[]
Definition: MMFMaxwell.h:51
SourceType
Definition: MMFMaxwell.h:58
@ ePointSource
Definition: MMFMaxwell.h:60
@ ePlanarSource
Definition: MMFMaxwell.h:61
@ SIZE_SourceType
Definition: MMFMaxwell.h:62
const char *const SourceTypeMap[]
Definition: MMFMaxwell.h:65
CloakType
Definition: MMFMaxwell.h:42
@ eOpticalCloak
Definition: MMFMaxwell.h:44
@ eMicroWaveCloak
Definition: MMFMaxwell.h:47
@ eOpticalDispersiveCloak
Definition: MMFMaxwell.h:46
@ eOpticalConstCloak
Definition: MMFMaxwell.h:45
@ SIZE_CloakType
Definition: MMFMaxwell.h:48
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
Definition: Timer.cpp:65
void Checkpoint_EDFluxOutput(const int n, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &fieldphys)
NekDouble m_CloakNlayer
Definition: MMFMaxwell.h:115
NekDouble m_PSduration
Definition: MMFMaxwell.h:123
CloakType m_CloakType
Definition: MMFMaxwell.h:78
Array< OneD, NekDouble > m_mu
Definition: MMFMaxwell.h:135
NekDouble m_PMLmaxsigma
Definition: MMFMaxwell.h:139
void AddCoriolis(Array< OneD, Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
void DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Compute the RHS.
Definition: MMFMaxwell.cpp:889
Array< OneD, NekDouble > TestMaxwellSphere(const NekDouble time, const NekDouble omega, unsigned int field)
Array< OneD, NekDouble > m_coriolis
Definition: MMFMaxwell.h:144
Array< OneD, Array< OneD, NekDouble > > m_CrossProductMF
Definition: MMFMaxwell.h:125
NekDouble m_Gaussianradius
Definition: MMFMaxwell.h:123
void WeakDGMaxwellDirDeriv(const Array< OneD, const Array< OneD, NekDouble > > &InField, Array< OneD, Array< OneD, NekDouble > > &OutField, const NekDouble time=0.0)
Calculate weak DG advection in the form .
NekDouble m_PMLstart
Definition: MMFMaxwell.h:139
Array< OneD, NekDouble > ComputeRadCloak(const int Nlayer=5)
void print_MMF(Array< OneD, Array< OneD, NekDouble > > &inarray)
Array< OneD, NekDouble > TestMaxwell2DPEC(const NekDouble time, unsigned int field, const SolverUtils::PolType Polarization)
Array< OneD, NekDouble > m_SourceVector
Definition: MMFMaxwell.h:121
NekDouble ComputeEnergyDensity(Array< OneD, Array< OneD, NekDouble > > &fields)
NekDouble m_Cloakraddelta
Definition: MMFMaxwell.h:116
static std::string className
Name of class.
Definition: MMFMaxwell.h:93
void Checkpoint_EnergyOutput(const int n, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &fieldphys)
~MMFMaxwell() override
Destructor.
Definition: MMFMaxwell.cpp:445
void Checkpoint_TotalFieldOutput(const int n, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &fieldphys)
void ComputeMaterialMicroWaveCloak(const Array< OneD, const NekDouble > &radvec, Array< OneD, Array< OneD, NekDouble > > &epsvec, Array< OneD, Array< OneD, NekDouble > > &muvec)
Array< OneD, NekDouble > ComputeSurfaceCurrent(const int time, const Array< OneD, const Array< OneD, NekDouble > > &fields)
Array< OneD, Array< OneD, NekDouble > > m_SigmaPML
Definition: MMFMaxwell.h:140
void Checkpoint_TotPlotOutput(const int n, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &fieldphys)
Array< OneD, NekDouble > m_varepsilon
Definition: MMFMaxwell.h:134
MMFMaxwell(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Session reader.
Definition: MMFMaxwell.cpp:55
void DoOdeProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Compute the projection.
void v_InitObject(bool DeclareFields=true) override
Initialise the object.
Definition: MMFMaxwell.cpp:64
void ComputeMaterialOpticalCloak(const Array< OneD, const NekDouble > &radvec, Array< OneD, Array< OneD, NekDouble > > &epsvec, Array< OneD, Array< OneD, NekDouble > > &muvec, const bool Dispersion=false)
void AddGreenDerivCompensate(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
SourceType m_SourceType
Definition: MMFMaxwell.h:79
void ComputeMaterialVector(Array< OneD, Array< OneD, NekDouble > > &epsvec, Array< OneD, Array< OneD, NekDouble > > &muvec)
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
Definition: MMFMaxwell.h:83
NekDouble m_freq
Definition: MMFMaxwell.h:131
int m_PrintoutSurfaceCurrent
Definition: MMFMaxwell.h:107
void GenerateSigmaPML(const NekDouble PMLthickness, const NekDouble PMLstart, const NekDouble PMLmaxsigma, Array< OneD, Array< OneD, NekDouble > > &SigmaPML)
NekDouble m_PMLthickness
Definition: MMFMaxwell.h:139
Array< OneD, NekDouble > GaussianPulse(const NekDouble time, const NekDouble Psx, const NekDouble Psy, const NekDouble Psz, const NekDouble Gaussianradius)
void Printout_SurfaceCurrent(Array< OneD, Array< OneD, NekDouble > > &fields, const int time)
void v_EvaluateExactSolution(unsigned int field, Array< OneD, NekDouble > &outfield, const NekDouble time) override
NekDouble m_wp2Tol
Definition: MMFMaxwell.h:118
void v_DoSolve() override
Solves an unsteady problem.
Definition: MMFMaxwell.cpp:449
Array< OneD, NekDouble > m_wp2
Definition: MMFMaxwell.h:119
void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print Summary.
void AddPML(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
void v_SetInitialConditions(const NekDouble initialtime, bool dumpInitialConditions, const int domain) override
Array< OneD, NekDouble > TestMaxwell2DPMC(const NekDouble time, unsigned int field, const SolverUtils::PolType Polarization)
Array< OneD, NekDouble > EvaluateCoriolis()
Array< OneD, NekDouble > TestMaxwell1D(const NekDouble time, unsigned int field)
void Checkpoint_PlotOutput(const int n, const Array< OneD, const Array< OneD, NekDouble > > &fieldphys)
int m_spacedim
Spatial dimension (>= expansion dim).
SOLVER_UTILS_EXPORT int GetTraceNpoints()
NekDouble m_timestep
Time step size.
int m_infosteps
Number of time steps between outputting status information.
NekDouble m_time
Current time of simulation.
SOLVER_UTILS_EXPORT int GetTraceTotPoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
NekDouble m_fintime
Finish time of the simulation.
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
NekDouble m_checktime
Time between checkpoints.
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
std::string m_sessionName
Name of the session.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
int m_steps
Number of steps to take.
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
int m_checksteps
Number of steps between checkpoints.
SOLVER_UTILS_EXPORT int GetTotPoints()
A base class for PDEs which include an advection component.
Definition: MMFSystem.h:144
SOLVER_UTILS_EXPORT void GetMaxwellFluxVector(const int var, const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &flux)
Definition: MMFSystem.cpp:1603
SOLVER_UTILS_EXPORT void v_GenerateSummary(SummaryList &s) override
Virtual function for generating summary information.
Definition: MMFSystem.cpp:2463
SOLVER_UTILS_EXPORT void DeriveCrossProductMF(Array< OneD, Array< OneD, NekDouble > > &CrossProductMF)
Definition: MMFSystem.cpp:568
SOLVER_UTILS_EXPORT void NumericalMaxwellFlux(Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &numfluxFwd, Array< OneD, Array< OneD, NekDouble > > &numfluxBwd, const NekDouble time=0.0)
Definition: MMFSystem.cpp:1724
SOLVER_UTILS_EXPORT void AdddedtMaxwell(const Array< OneD, const Array< OneD, NekDouble > > &physarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
Definition: MMFSystem.cpp:1364
SOLVER_UTILS_EXPORT void ComputeZimYim(Array< OneD, Array< OneD, NekDouble > > &epsvec, Array< OneD, Array< OneD, NekDouble > > &muvec)
Definition: MMFSystem.cpp:1102
Array< OneD, Array< OneD, NekDouble > > m_muvec
Definition: MMFSystem.h:210
SpatialDomains::GeomMMF m_MMFdir
Definition: MMFSystem.h:219
Array< OneD, Array< OneD, NekDouble > > m_movingframes
Definition: MMFSystem.h:183
Array< OneD, NekDouble > m_MMFfactors
Definition: MMFSystem.h:157
SOLVER_UTILS_EXPORT Array< OneD, NekDouble > GetIncidentField(const int var, const NekDouble time)
Definition: MMFSystem.cpp:2005
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_ntimesMFFwd
Definition: MMFSystem.h:199
Array< OneD, Array< OneD, NekDouble > > m_negepsvecminus1
Definition: MMFSystem.h:212
SOLVER_UTILS_EXPORT Array< OneD, NekDouble > CartesianToMovingframes(const Array< OneD, const Array< OneD, NekDouble > > &uvec, unsigned int field)
Definition: MMFSystem.cpp:771
Array< OneD, Array< OneD, NekDouble > > m_epsvec
Definition: MMFSystem.h:209
SOLVER_UTILS_EXPORT void CartesianToSpherical(const NekDouble x0j, const NekDouble x1j, const NekDouble x2j, NekDouble &sin_varphi, NekDouble &cos_varphi, NekDouble &sin_theta, NekDouble &cos_theta)
Definition: MMFSystem.cpp:792
Array< OneD, Array< OneD, NekDouble > > m_negmuvecminus1
Definition: MMFSystem.h:213
SOLVER_UTILS_EXPORT void ComputeNtimesMF()
Definition: MMFSystem.cpp:615
SOLVER_UTILS_EXPORT NekDouble RootMeanSquare(const Array< OneD, const NekDouble > &inarray)
Definition: MMFSystem.cpp:2338
SOLVER_UTILS_EXPORT void MMFInitObject(const Array< OneD, const Array< OneD, NekDouble > > &Anisotropy, const int TangentXelem=-1)
Definition: MMFSystem.cpp:51
TestMaxwellType m_TestMaxwellType
Definition: MMFSystem.h:153
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_CurlMF
Definition: MMFSystem.h:193
SOLVER_UTILS_EXPORT void Computedemdxicdote()
Definition: MMFSystem.cpp:1274
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
LibUtilities::TimeIntegrationSchemeSharedPtr m_intScheme
Wrapper to the time integration scheme.
bool m_explicitAdvection
Indicates if explicit or implicit treatment of advection is used.
SOLVER_UTILS_EXPORT void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
static NekDouble rad(NekDouble x, NekDouble y)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
static const NekDouble kNekZeroTol
const char *const IncTypeMap[]
Definition: MMFSystem.h:136
std::vector< std::pair< std::string, std::string > > SummaryList
Definition: Misc.h:46
@ SIZE_TestMaxwellType
Length of enum list.
Definition: MMFSystem.h:105
EquationSystemFactory & GetEquationSystemFactory()
const char *const TestMaxwellTypeMap[]
Definition: MMFSystem.h:108
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
Definition: Misc.cpp:47
const char *const PolTypeMap[]
Definition: MMFSystem.h:123
@ eTangentIrregular
Circular around the centre of domain.
@ eTangentCircular
Circular around the centre of domain.
@ eTangentNonconvex
Circular around the centre of domain.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::vector< double > z(NPUPPER)
double NekDouble
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.hpp:340
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.hpp:72
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition: Vmath.hpp:396
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.hpp:292
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.hpp:725
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.hpp:366
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.hpp:180
void Vvtvm(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvm (vector times vector minus vector): z = w*x - y
Definition: Vmath.hpp:381
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100
void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x/y.
Definition: Vmath.hpp:126
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273
T Vamax(int n, const T *x, const int incx)
Return the maximum absolute element in x called vamax to avoid conflict with max.
Definition: Vmath.hpp:685
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
Definition: Vmath.hpp:194
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.hpp:644
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.hpp:220
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294