xref: /libCEED/examples/fluids/problems/densitycurrent.c (revision c95f9967850094821b23829a90999d6fd511c6a5)
1 // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other
2 // CEED contributors. All Rights Reserved. See the top-level LICENSE and NOTICE
3 // files for details.
4 //
5 // SPDX-License-Identifier: BSD-2-Clause
6 //
7 // This file is part of CEED:  http://github.com/ceed
8 
9 /// @file
10 /// Utility functions for setting up DENSITY_CURRENT
11 
12 #include "../qfunctions/densitycurrent.h"
13 #include "../navierstokes.h"
14 
15 PetscErrorCode NS_DENSITY_CURRENT(ProblemData *problem, DM dm, void *setup_ctx,
16                                   void *ctx) {
17 
18   PetscInt ierr;
19   ierr = NS_NEWTONIAN_IG(problem, dm, setup_ctx, ctx);
20   CHKERRQ(ierr);
21   SetupContext setup_context = *(SetupContext *)setup_ctx;
22   User user = *(User *)ctx;
23   MPI_Comm comm = PETSC_COMM_WORLD;
24   PetscFunctionBeginUser;
25 
26   // ------------------------------------------------------
27   //               SET UP DENSITY_CURRENT
28   // ------------------------------------------------------
29   problem->ics.qfunction = ICsDC;
30   problem->ics.qfunction_loc = ICsDC_loc;
31   problem->bc = Exact_DC;
32   problem->bc_ctx = setup_ctx;
33 
34   // ------------------------------------------------------
35   //             Create the libCEED context
36   // ------------------------------------------------------
37   CeedScalar theta0 = 300.; // K
38   CeedScalar thetaC = -15.; // K
39   CeedScalar P0 = 1.e5;     // Pa
40   CeedScalar N = 0.01;      // 1/s
41   CeedScalar rc = 1000.;    // m (Radius of bubble)
42   PetscReal center[3], dc_axis[3] = {0, 0, 0};
43   PetscReal domain_min[3], domain_max[3], domain_size[3];
44   ierr = DMGetBoundingBox(dm, domain_min, domain_max);
45   CHKERRQ(ierr);
46   for (int i = 0; i < 3; i++)
47     domain_size[i] = domain_max[i] - domain_min[i];
48 
49   // ------------------------------------------------------
50   //              Command line Options
51   // ------------------------------------------------------
52   PetscOptionsBegin(comm, NULL, "Options for DENSITY_CURRENT problem", NULL);
53   ierr = PetscOptionsScalar("-theta0", "Reference potential temperature", NULL,
54                             theta0, &theta0, NULL);
55   CHKERRQ(ierr);
56   ierr = PetscOptionsScalar("-thetaC", "Perturbation of potential temperature",
57                             NULL, thetaC, &thetaC, NULL);
58   CHKERRQ(ierr);
59   ierr = PetscOptionsScalar("-P0", "Atmospheric pressure", NULL, P0, &P0, NULL);
60   CHKERRQ(ierr);
61   ierr = PetscOptionsScalar("-N", "Brunt-Vaisala frequency", NULL, N, &N, NULL);
62   CHKERRQ(ierr);
63   ierr = PetscOptionsScalar("-rc", "Characteristic radius of thermal bubble",
64                             NULL, rc, &rc, NULL);
65   CHKERRQ(ierr);
66   for (int i = 0; i < 3; i++)
67     center[i] = .5 * domain_size[i];
68   PetscInt n = problem->dim;
69   ierr = PetscOptionsRealArray("-center", "Location of bubble center", NULL,
70                                center, &n, NULL);
71   CHKERRQ(ierr);
72   n = problem->dim;
73   ierr = PetscOptionsRealArray("-dc_axis",
74                                "Axis of density current cylindrical anomaly, "
75                                "or {0,0,0} for spherically symmetric",
76                                NULL, dc_axis, &n, NULL);
77   CHKERRQ(ierr);
78   {
79     PetscReal norm = PetscSqrtReal(PetscSqr(dc_axis[0]) + PetscSqr(dc_axis[1]) +
80                                    PetscSqr(dc_axis[2]));
81     if (norm > 0) {
82       for (int i = 0; i < 3; i++)
83         dc_axis[i] /= norm;
84     }
85   }
86 
87   PetscOptionsEnd();
88 
89   PetscScalar meter           = user->units->meter;
90   PetscScalar second          = user->units->second;
91   PetscScalar Kelvin          = user->units->Kelvin;
92   PetscScalar Pascal          = user->units->Pascal;
93   rc = fabs(rc) * meter;
94   theta0 *= Kelvin;
95   thetaC *= Kelvin;
96   P0 *= Pascal;
97   N *= (1. / second);
98   for (int i = 0; i < 3; i++)
99     center[i] *= meter;
100 
101   setup_context->theta0 = theta0;
102   setup_context->thetaC = thetaC;
103   setup_context->P0 = P0;
104   setup_context->N = N;
105   setup_context->rc = rc;
106   setup_context->center[0] = center[0];
107   setup_context->center[1] = center[1];
108   setup_context->center[2] = center[2];
109   setup_context->dc_axis[0] = dc_axis[0];
110   setup_context->dc_axis[1] = dc_axis[1];
111   setup_context->dc_axis[2] = dc_axis[2];
112 
113   PetscFunctionReturn(0);
114 }
115