/home/runner/work/amr-wind/amr-wind/amr-wind/equation_systems/icns/icns_diffusion.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/equation_systems/icns/icns_diffusion.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
icns_diffusion.H
Go to the documentation of this file.
1#ifndef ICNS_DIFFUSION_H
2#define ICNS_DIFFUSION_H
3
4#include <memory>
5
12
13namespace amr_wind::pde {
14
15class ICNSDiffTensorOp : public DiffSolverIface<amrex::MLTensorOp>
16{
17public:
19 PDEFields& fields, const bool has_overset, const bool mesh_mapping)
20 : DiffSolverIface<amrex::MLTensorOp>(fields, has_overset, mesh_mapping)
21 {
22 this->m_solver->setDomainBC(
24 this->m_pdefields.field, amrex::Orientation::low),
26 this->m_pdefields.field, amrex::Orientation::high));
27 this->m_applier->setDomainBC(
29 this->m_pdefields.field, amrex::Orientation::low),
31 this->m_pdefields.field, amrex::Orientation::high));
32 }
33
34 template <typename Scheme>
35 void compute_diff_term(const FieldState fstate)
36 {
37 this->setup_operator(*this->m_applier, 0.0, -1.0, fstate);
38
39 auto tau_state = std::is_same<Scheme, fvm::Godunov>::value
41 : fstate;
42 auto& divtau = this->m_pdefields.diff_term.state(tau_state);
43
44 amrex::MLMG mlmg(*this->m_applier);
45 mlmg.apply(divtau.vec_ptrs(), this->m_pdefields.field.vec_ptrs());
46 }
47};
48
50{
51public:
53 PDEFields& fields,
54 const bool has_overset,
55 const bool mesh_mapping,
56 const std::string& prefix = "diffusion")
57 : m_pdefields(fields)
58 , m_density(fields.repo.get_field("density"))
59 , m_options(prefix, m_pdefields.field.name() + "_" + prefix)
60 , m_mesh_mapping(mesh_mapping)
61 {
62 amrex::LPInfo isolve = m_options.lpinfo();
63 amrex::LPInfo iapply;
64
65 iapply.setMaxCoarseningLevel(0);
66 const auto& mesh = m_pdefields.repo.mesh();
67
68 const auto& bclo = diffusion::get_diffuse_tensor_bc(
69 m_pdefields.field, amrex::Orientation::low);
70 const auto& bchi = diffusion::get_diffuse_tensor_bc(
71 m_pdefields.field, amrex::Orientation::high);
72
73 if (!has_overset) {
74
75 m_solver_scalar = std::make_unique<amrex::MLABecLaplacian>(
76 mesh.Geom(0, mesh.finestLevel()),
77 mesh.boxArray(0, mesh.finestLevel()),
78 mesh.DistributionMap(0, mesh.finestLevel()), isolve,
79 amrex::Vector<
80 amrex::FabFactory<amrex::MLABecLaplacian::FAB> const*>(),
81 AMREX_SPACEDIM);
82 m_applier_scalar = std::make_unique<amrex::MLABecLaplacian>(
83 mesh.Geom(0, mesh.finestLevel()),
84 mesh.boxArray(0, mesh.finestLevel()),
85 mesh.DistributionMap(0, mesh.finestLevel()), iapply,
86 amrex::Vector<
87 amrex::FabFactory<amrex::MLABecLaplacian::FAB> const*>(),
88 AMREX_SPACEDIM);
89 } else {
90 auto imask =
91 fields.repo.get_int_field("mask_cell").vec_const_ptrs();
92 m_solver_scalar = std::make_unique<amrex::MLABecLaplacian>(
93 mesh.Geom(0, mesh.finestLevel()),
94 mesh.boxArray(0, mesh.finestLevel()),
95 mesh.DistributionMap(0, mesh.finestLevel()), imask, isolve,
96 amrex::Vector<
97 amrex::FabFactory<amrex::MLABecLaplacian::FAB> const*>(),
98 AMREX_SPACEDIM);
99 m_applier_scalar = std::make_unique<amrex::MLABecLaplacian>(
100 mesh.Geom(0, mesh.finestLevel()),
101 mesh.boxArray(0, mesh.finestLevel()),
102 mesh.DistributionMap(0, mesh.finestLevel()), imask, iapply,
103 amrex::Vector<
104 amrex::FabFactory<amrex::MLABecLaplacian::FAB> const*>(),
105 AMREX_SPACEDIM);
106 }
107
108 m_solver_scalar->setMaxOrder(m_options.max_order);
110
111 m_solver_scalar->setDomainBC(bclo, bchi);
112 m_applier_scalar->setDomainBC(bclo, bchi);
113 }
114
115 template <typename Scheme>
116 void compute_diff_term(const FieldState fstate)
117 {
118 auto tau_state = std::is_same<Scheme, fvm::Godunov>::value
120 : fstate;
121 const auto& repo = m_pdefields.repo;
122 const int nlevels = repo.num_active_levels();
123 const auto& geom = repo.mesh().Geom();
124
125 bool diff_for_RHS(fstate == amr_wind::FieldState::New);
126 auto& divtau = m_pdefields.diff_term.state(tau_state);
127 const auto& density = m_density.state(fstate);
128 const auto& viscosity = m_pdefields.mueff;
129 Field const* mesh_detJ =
130 m_mesh_mapping ? &(repo.get_mesh_mapping_det_j(FieldLoc::CELL))
131 : nullptr;
132 std::unique_ptr<ScratchField> rho_times_detJ =
133 m_mesh_mapping ? repo.create_scratch_field(
135 : nullptr;
136
137 const amrex::Real alpha = 0.0;
138 const amrex::Real beta = -1.0;
139 m_applier_scalar->setScalars(alpha, beta);
140
141 for (int lev = 0; lev < nlevels; ++lev) {
142 m_applier_scalar->setLevelBC(lev, &m_pdefields.field(lev));
143
144 // A coeffs
145 if (m_mesh_mapping) {
146 (*rho_times_detJ)(lev).setVal(0.0);
147 amrex::MultiFab::AddProduct(
148 (*rho_times_detJ)(lev), density(lev), 0, (*mesh_detJ)(lev),
149 0, 0, 1, m_density.num_grow()[0]);
150 m_applier_scalar->setACoeffs(lev, (*rho_times_detJ)(lev));
151 } else {
152 m_applier_scalar->setACoeffs(lev, density(lev));
153 }
154
155 // B coeffs
157 geom[lev], viscosity(lev));
158 if (m_mesh_mapping) {
160 }
161 m_applier_scalar->setBCoeffs(lev, amrex::GetArrOfConstPtrs(b));
162 }
163
164 amrex::MLMG mlmg(*m_applier_scalar);
165 mlmg.apply(divtau.vec_ptrs(), m_pdefields.field.vec_ptrs());
166
167 if (!diff_for_RHS) {
168 for (int lev = 0; lev < nlevels; ++lev) {
169#ifdef AMREX_USE_OMP
170#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
171#endif
172 for (amrex::MFIter mfi(divtau(lev), amrex::TilingIfNotGPU());
173 mfi.isValid(); ++mfi) {
174 const auto& bx = mfi.tilebox();
175 const auto& divtau_arr = divtau(lev).array(mfi);
176 const auto& rho_arr = density(lev).const_array(mfi);
177
178 amrex::ParallelFor(
179 bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
180 amrex::Real rhoinv = 1.0 / rho_arr(i, j, k);
181 divtau_arr(i, j, k, 0) *= rhoinv;
182 divtau_arr(i, j, k, 1) *= rhoinv;
183 divtau_arr(i, j, k, 2) *= rhoinv;
184 });
185 }
186 }
187 }
188 }
189
190 void linsys_solve(const amrex::Real dt)
191 {
192 const FieldState fstate = FieldState::New;
193 auto& repo = m_pdefields.repo;
194 const auto& geom = repo.mesh().Geom();
195 const auto& field = m_pdefields.field;
196 const auto& density = m_density.state(fstate);
197 const int nlevels = repo.num_active_levels();
198 const int ndim = field.num_comp();
199 auto rhs_ptr = repo.create_scratch_field("rhs", field.num_comp(), 0);
200 const auto& viscosity = m_pdefields.mueff;
201 Field const* mesh_detJ =
202 m_mesh_mapping ? &(repo.get_mesh_mapping_det_j(FieldLoc::CELL))
203 : nullptr;
204 std::unique_ptr<ScratchField> rho_times_detJ =
205 m_mesh_mapping ? repo.create_scratch_field(
207 : nullptr;
208
209 const amrex::Real alpha = 1.0;
210 const amrex::Real beta = dt;
211 m_solver_scalar->setScalars(alpha, beta);
212
213 for (int lev = 0; lev < nlevels; ++lev) {
214 m_solver_scalar->setLevelBC(lev, &m_pdefields.field(lev));
215
216 // A coeffs
217 if (m_mesh_mapping) {
218 (*rho_times_detJ)(lev).setVal(0.0);
219 amrex::MultiFab::AddProduct(
220 (*rho_times_detJ)(lev), density(lev), 0, (*mesh_detJ)(lev),
221 0, 0, 1, m_density.num_grow()[0]);
222 m_solver_scalar->setACoeffs(lev, (*rho_times_detJ)(lev));
223 } else {
224 m_solver_scalar->setACoeffs(lev, density(lev));
225 }
226
227 // B coeffs
229 geom[lev], viscosity(lev));
230 if (m_mesh_mapping) {
232 }
233 m_solver_scalar->setBCoeffs(lev, amrex::GetArrOfConstPtrs(b));
234 }
235
236 // Always multiply with rho since there is no diffusion term for density
237 for (int lev = 0; lev < nlevels; ++lev) {
238 auto& rhs = (*rhs_ptr)(lev);
239
240#ifdef AMREX_USE_OMP
241#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
242#endif
243 for (amrex::MFIter mfi(rhs, amrex::TilingIfNotGPU()); mfi.isValid();
244 ++mfi) {
245 const auto& bx = mfi.tilebox();
246 const auto& rhs_a = rhs.array(mfi);
247 const auto& fld = field(lev).const_array(mfi);
248 const auto& rho = density(lev).const_array(mfi);
249
250 amrex::ParallelFor(
251 bx, ndim,
252 [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept {
253 rhs_a(i, j, k, n) = rho(i, j, k) * fld(i, j, k, n);
254 });
255 }
256 }
257
258 amrex::MLMG mlmg(*m_solver_scalar);
259 m_options(mlmg);
260 mlmg.solve(
261 m_pdefields.field.vec_ptrs(), rhs_ptr->vec_const_ptrs(),
263
264 io::print_mlmg_info(field.name() + "_multicomponent_solve", mlmg);
265 }
266
267protected:
271 bool m_mesh_mapping{false};
272
273 std::unique_ptr<amrex::MLABecLaplacian> m_solver_scalar;
274 std::unique_ptr<amrex::MLABecLaplacian> m_applier_scalar;
275};
276
278{
279public:
281 PDEFields& fields,
282 const bool has_overset,
283 const bool mesh_mapping,
284 const std::string& prefix = "diffusion")
285 : m_pdefields(fields)
286 , m_density(fields.repo.get_field("density"))
287 , m_options(prefix, m_pdefields.field.name() + "_" + prefix)
288 , m_mesh_mapping(mesh_mapping)
289 {
290 amrex::LPInfo isolve = m_options.lpinfo();
291 amrex::LPInfo iapply;
292
293 iapply.setMaxCoarseningLevel(0);
294 const auto& mesh = m_pdefields.repo.mesh();
295
296 const auto& bclo = diffusion::get_diffuse_tensor_bc(
297 m_pdefields.field, amrex::Orientation::low);
298 const auto& bchi = diffusion::get_diffuse_tensor_bc(
299 m_pdefields.field, amrex::Orientation::high);
300
301 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
302 if (!has_overset) {
303 m_solver_scalar[i] = std::make_unique<amrex::MLABecLaplacian>(
304 mesh.Geom(0, mesh.finestLevel()),
305 mesh.boxArray(0, mesh.finestLevel()),
306 mesh.DistributionMap(0, mesh.finestLevel()), isolve);
307 m_applier_scalar[i] = std::make_unique<amrex::MLABecLaplacian>(
308 mesh.Geom(0, mesh.finestLevel()),
309 mesh.boxArray(0, mesh.finestLevel()),
310 mesh.DistributionMap(0, mesh.finestLevel()), iapply);
311 } else {
312 auto imask =
313 fields.repo.get_int_field("mask_cell").vec_const_ptrs();
314 m_solver_scalar[i] = std::make_unique<amrex::MLABecLaplacian>(
315 mesh.Geom(0, mesh.finestLevel()),
316 mesh.boxArray(0, mesh.finestLevel()),
317 mesh.DistributionMap(0, mesh.finestLevel()), imask, isolve);
318 m_applier_scalar[i] = std::make_unique<amrex::MLABecLaplacian>(
319 mesh.Geom(0, mesh.finestLevel()),
320 mesh.boxArray(0, mesh.finestLevel()),
321 mesh.DistributionMap(0, mesh.finestLevel()), imask, iapply);
322 }
323
324 m_solver_scalar[i]->setMaxOrder(m_options.max_order);
325 m_applier_scalar[i]->setMaxOrder(m_options.max_order);
326
327 m_solver_scalar[i]->setDomainBC(bclo[i], bchi[i]);
328 m_applier_scalar[i]->setDomainBC(bclo[i], bchi[i]);
329 }
330 }
331
332 template <typename Scheme>
333 void compute_diff_term(const FieldState fstate)
334 {
335 auto tau_state = std::is_same<Scheme, fvm::Godunov>::value
337 : fstate;
338 const auto& repo = m_pdefields.repo;
339 const int nlevels = repo.num_active_levels();
340 const auto& geom = repo.mesh().Geom();
341
342 auto& divtau = m_pdefields.diff_term.state(tau_state);
343 bool diff_for_RHS(fstate == amr_wind::FieldState::New);
344 const auto& density = m_density.state(fstate);
345 const auto& viscosity = m_pdefields.mueff;
346 Field const* mesh_detJ =
347 m_mesh_mapping ? &(repo.get_mesh_mapping_det_j(FieldLoc::CELL))
348 : nullptr;
349 std::unique_ptr<ScratchField> rho_times_detJ =
350 m_mesh_mapping ? repo.create_scratch_field(
352 : nullptr;
353
354 const amrex::Real alpha = 0.0;
355 const amrex::Real beta = -1.0;
356
357 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
358 m_applier_scalar[i]->setScalars(alpha, beta);
359
360 for (int lev = 0; lev < nlevels; ++lev) {
361
362 m_applier_scalar[i]->setLevelBC(
363 lev, &m_pdefields.field.subview(i)(lev));
364
365 if (m_mesh_mapping) {
366 (*rho_times_detJ)(lev).setVal(0.0);
367 amrex::MultiFab::AddProduct(
368 (*rho_times_detJ)(lev), density(lev), 0,
369 (*mesh_detJ)(lev), 0, 0, 1, m_density.num_grow()[0]);
370 }
371
372 // A coeffs
373 if (m_mesh_mapping) {
374 m_applier_scalar[i]->setACoeffs(
375 lev, (*rho_times_detJ)(lev));
376 } else {
377 m_applier_scalar[i]->setACoeffs(lev, density(lev));
378 }
379
380 // B coeffs
382 geom[lev], viscosity(lev));
383
384 if (m_mesh_mapping) {
386 }
387
388 m_applier_scalar[i]->setBCoeffs(
389 lev, amrex::GetArrOfConstPtrs(b));
390 }
391
392 auto divtau_comp = divtau.subview(i);
393 auto vel_comp = m_pdefields.field.subview(i);
394
395 amrex::MLMG mlmg(*m_applier_scalar[i]);
396 mlmg.apply(divtau_comp.vec_ptrs(), vel_comp.vec_ptrs());
397 }
398
399 if (!diff_for_RHS) {
400 for (int lev = 0; lev < nlevels; ++lev) {
401#ifdef AMREX_USE_OMP
402#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
403#endif
404 for (amrex::MFIter mfi(divtau(lev), amrex::TilingIfNotGPU());
405 mfi.isValid(); ++mfi) {
406 const auto& bx = mfi.tilebox();
407 const auto& divtau_arr = divtau(lev).array(mfi);
408 const auto& rho_arr = density(lev).const_array(mfi);
409
410 amrex::ParallelFor(
411 bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
412 amrex::Real rhoinv = 1.0 / rho_arr(i, j, k);
413 divtau_arr(i, j, k, 0) *= rhoinv;
414 divtau_arr(i, j, k, 1) *= rhoinv;
415 divtau_arr(i, j, k, 2) *= rhoinv;
416 });
417 }
418 }
419 }
420 }
421
422 void linsys_solve(const amrex::Real dt)
423 {
424 const FieldState fstate = FieldState::New;
425 auto& repo = m_pdefields.repo;
426 const auto& field = m_pdefields.field;
427 const auto& density = m_density.state(fstate);
428 const int nlevels = repo.num_active_levels();
429 const int ndim = field.num_comp();
430 auto rhs_ptr = repo.create_scratch_field("rhs", field.num_comp(), 0);
431 const auto& viscosity = m_pdefields.mueff;
432 const auto& geom = repo.mesh().Geom();
433
434 Field const* mesh_detJ =
435 m_mesh_mapping ? &(repo.get_mesh_mapping_det_j(FieldLoc::CELL))
436 : nullptr;
437 std::unique_ptr<ScratchField> rho_times_detJ =
438 m_mesh_mapping ? repo.create_scratch_field(
440 : nullptr;
441
442 const amrex::Real alpha = 1.0;
443 const amrex::Real beta = dt;
444
445 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
446 m_solver_scalar[i]->setScalars(alpha, beta);
447
448 for (int lev = 0; lev < nlevels; ++lev) {
449
450 if (m_mesh_mapping) {
451 (*rho_times_detJ)(lev).setVal(0.0);
452 amrex::MultiFab::AddProduct(
453 (*rho_times_detJ)(lev), density(lev), 0,
454 (*mesh_detJ)(lev), 0, 0, 1, m_density.num_grow()[0]);
455 }
456
457 m_solver_scalar[i]->setLevelBC(
458 lev, &m_pdefields.field.subview(i)(lev));
459
460 // A coeffs
461 if (m_mesh_mapping) {
462 m_solver_scalar[i]->setACoeffs(lev, (*rho_times_detJ)(lev));
463 } else {
464 m_solver_scalar[i]->setACoeffs(lev, density(lev));
465 }
466
467 // B coeffs
469 geom[lev], viscosity(lev));
470 if (m_mesh_mapping) {
472 }
473
474 m_solver_scalar[i]->setBCoeffs(
475 lev, amrex::GetArrOfConstPtrs(b));
476 }
477 }
478
479 // Always multiply with rho since there is no diffusion term for density
480 for (int lev = 0; lev < nlevels; ++lev) {
481 auto& rhs = (*rhs_ptr)(lev);
482
483#ifdef AMREX_USE_OMP
484#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
485#endif
486 for (amrex::MFIter mfi(rhs, amrex::TilingIfNotGPU()); mfi.isValid();
487 ++mfi) {
488 const auto& bx = mfi.tilebox();
489 const auto& rhs_a = rhs.array(mfi);
490 const auto& fld = field(lev).const_array(mfi);
491 const auto& rho = density(lev).const_array(mfi);
492
493 amrex::ParallelFor(
494 bx, ndim,
495 [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept {
496 rhs_a(i, j, k, n) = rho(i, j, k) * fld(i, j, k, n);
497 });
498 }
499 }
500
501 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
502 auto vel_comp = m_pdefields.field.subview(i);
503 auto rhs_ptr_comp = rhs_ptr->subview(i);
504
505 amrex::MLMG mlmg(*m_solver_scalar[i]);
506 m_options(mlmg);
507
508 mlmg.solve(
509 vel_comp.vec_ptrs(), rhs_ptr_comp.vec_const_ptrs(),
511
513 field.name() + std::to_string(i) + "_solve", mlmg);
514 }
515 }
516
517protected:
521 bool m_mesh_mapping{false};
522
523 amrex::Array<std::unique_ptr<amrex::MLABecLaplacian>, AMREX_SPACEDIM>
525 amrex::Array<std::unique_ptr<amrex::MLABecLaplacian>, AMREX_SPACEDIM>
527};
528
532template <typename Scheme>
533struct DiffusionOp<ICNS, Scheme>
534{
535 std::unique_ptr<ICNSDiffTensorOp> m_tensor_op;
536 std::unique_ptr<ICNSDiffScalarOp> m_scalar_op;
537 std::unique_ptr<ICNSDiffScalarSegregatedOp> m_scalar_segregated_op;
538
539 static_assert(
540 ICNS::ndim == AMREX_SPACEDIM,
541 "DiffusionOp invoked for scalar PDE type");
542
543 bool use_segregated_op = false;
544
546 PDEFields& fields, const bool has_overset, const bool mesh_mapping)
547 {
548 bool use_tensor_op = true;
549
550 amrex::ParmParse pp(fields.field.name() + "_diffusion");
551 pp.query("use_tensor_operator", use_tensor_op);
552 pp.query("use_segregated_operator", use_segregated_op);
553
554 if (use_tensor_op && use_segregated_op) {
555 amrex::Abort(
556 "Tensor and segregated operators should not be enabled "
557 "simultaneously.");
558 }
559
560 if (use_tensor_op) {
561 m_tensor_op = std::make_unique<ICNSDiffTensorOp>(
562 fields, has_overset, mesh_mapping);
563 } else {
564 if (use_segregated_op) {
565 m_scalar_segregated_op =
566 std::make_unique<ICNSDiffScalarSegregatedOp>(
567 fields, has_overset, mesh_mapping);
568 } else {
569 m_scalar_op = std::make_unique<ICNSDiffScalarOp>(
570 fields, has_overset, mesh_mapping);
571 }
572 }
573 }
574
575 void compute_diff_term(const FieldState fstate)
576 {
577 if (m_tensor_op) {
578 m_tensor_op->compute_diff_term<Scheme>(fstate);
579 } else {
580 if (use_segregated_op) {
581 m_scalar_segregated_op->compute_diff_term<Scheme>(fstate);
582 } else {
583 m_scalar_op->compute_diff_term<Scheme>(fstate);
584 }
585 }
586 }
587
588 void linsys_solve(const amrex::Real dt)
589 {
590 if (m_tensor_op) {
591 m_tensor_op->linsys_solve(dt);
592 } else {
593 if (use_segregated_op) {
594 m_scalar_segregated_op->linsys_solve(dt);
595 } else {
596 m_scalar_op->linsys_solve(dt);
597 }
598 }
599 }
600};
601
602} // namespace amr_wind::pde
603
604#endif /* ICNS_DIFFUSION_H */
Definition Field.H:116
ViewField< Field > subview(const int scomp=0, const int ncomp=1)
Definition Field.H:296
const amrex::IntVect & num_grow() const
Ghost cells.
Definition Field.H:137
const std::string & name() const
Name of this field (including state information)
Definition Field.H:125
int num_comp() const
Number of components for this field.
Definition Field.H:134
amrex::Vector< amrex::MultiFab * > vec_ptrs() noexcept
Return a vector of MultiFab pointers for all levels.
Definition Field.cpp:142
Field & state(const FieldState fstate)
Return field at a different time state.
Definition Field.cpp:114
int num_active_levels() const noexcept
Total number of levels currently active in the AMR mesh.
Definition FieldRepo.H:361
IntField & get_int_field(const std::string &name, const FieldState fstate=FieldState::New) const
Return a reference to an integer field.
Definition FieldRepo.cpp:276
const amrex::AmrCore & mesh() const
Return a reference to the underlying AMR mesh instance.
Definition FieldRepo.H:358
amrex::Vector< const amrex::iMultiFab * > vec_const_ptrs() const noexcept
Definition IntField.cpp:46
Definition DiffusionOps.H:30
PDEFields & m_pdefields
Definition DiffusionOps.H:100
std::unique_ptr< amrex::MLTensorOp > m_applier
Definition DiffusionOps.H:108
virtual void setup_operator(amrex::MLTensorOp &linop, const amrex::Real alpha, const amrex::Real beta, const FieldState fstate)
Definition DiffusionOps.cpp:54
std::unique_ptr< amrex::MLTensorOp > m_solver
Definition DiffusionOps.H:107
Definition icns_diffusion.H:50
void compute_diff_term(const FieldState fstate)
Definition icns_diffusion.H:116
ICNSDiffScalarOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping, const std::string &prefix="diffusion")
Definition icns_diffusion.H:52
void linsys_solve(const amrex::Real dt)
Definition icns_diffusion.H:190
bool m_mesh_mapping
Definition icns_diffusion.H:271
std::unique_ptr< amrex::MLABecLaplacian > m_solver_scalar
Definition icns_diffusion.H:273
Field & m_density
Definition icns_diffusion.H:269
MLMGOptions m_options
Definition icns_diffusion.H:270
PDEFields & m_pdefields
Definition icns_diffusion.H:268
std::unique_ptr< amrex::MLABecLaplacian > m_applier_scalar
Definition icns_diffusion.H:274
Definition icns_diffusion.H:278
MLMGOptions m_options
Definition icns_diffusion.H:520
amrex::Array< std::unique_ptr< amrex::MLABecLaplacian >, AMREX_SPACEDIM > m_solver_scalar
Definition icns_diffusion.H:524
void compute_diff_term(const FieldState fstate)
Definition icns_diffusion.H:333
void linsys_solve(const amrex::Real dt)
Definition icns_diffusion.H:422
PDEFields & m_pdefields
Definition icns_diffusion.H:518
Field & m_density
Definition icns_diffusion.H:519
ICNSDiffScalarSegregatedOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping, const std::string &prefix="diffusion")
Definition icns_diffusion.H:280
bool m_mesh_mapping
Definition icns_diffusion.H:521
amrex::Array< std::unique_ptr< amrex::MLABecLaplacian >, AMREX_SPACEDIM > m_applier_scalar
Definition icns_diffusion.H:526
Definition icns_diffusion.H:16
ICNSDiffTensorOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping)
Definition icns_diffusion.H:18
void compute_diff_term(const FieldState fstate)
Definition icns_diffusion.H:35
FieldState
Definition FieldDescTypes.H:14
@ CELL
Cell-centered (default)
@ New
Same as FieldState::NP1.
void print_mlmg_info(const std::string &solve_name, const amrex::MLMG &mlmg)
Definition console_io.cpp:168
Definition AdvOp_Godunov.H:16
Definition console_io.cpp:25
void viscosity_to_uniform_space(amrex::Array< amrex::MultiFab, AMREX_SPACEDIM > &b, const amr_wind::FieldRepo &repo, int lev)
Definition incflo_diffusion.cpp:205
amrex::Vector< amrex::Array< amrex::LinOpBCType, AMREX_SPACEDIM > > get_diffuse_tensor_bc(amr_wind::Field &velocity, amrex::Orientation::Side side) noexcept
amrex::Array< amrex::MultiFab, AMREX_SPACEDIM > average_velocity_eta_to_faces(const amrex::Geometry &geom, amrex::MultiFab const &cc_eta)
Definition MLMGOptions.H:25
amrex::LPInfo & lpinfo()
Linear operator options during construction.
Definition MLMGOptions.H:48
int max_order
Definition MLMGOptions.H:51
amrex::Real abs_tol
Absolute tolerance for convergence checks.
Definition MLMGOptions.H:57
amrex::Real rel_tol
Relative tolerance for convergence of MLMG solvers.
Definition MLMGOptions.H:54
DiffusionOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping)
Definition icns_diffusion.H:545
void linsys_solve(const amrex::Real dt)
Definition icns_diffusion.H:588
std::unique_ptr< ICNSDiffScalarSegregatedOp > m_scalar_segregated_op
Definition icns_diffusion.H:537
void compute_diff_term(const FieldState fstate)
Definition icns_diffusion.H:575
std::unique_ptr< ICNSDiffScalarOp > m_scalar_op
Definition icns_diffusion.H:536
std::unique_ptr< ICNSDiffTensorOp > m_tensor_op
Definition icns_diffusion.H:535
Definition PDEOps.H:172
Definition icns.H:34
static constexpr int ndim
Definition icns.H:40
Definition PDEFields.H:27
Field & diff_term
Diffusion term for this PDE.
Definition PDEFields.H:41
Field & mueff
Effective visocity field (e.g., velocity_mueff)
Definition PDEFields.H:36
FieldRepo & repo
Reference to the field repository instance.
Definition PDEFields.H:31
Field & field
Solution variable (e.g., velocity, temperature)
Definition PDEFields.H:34