Skip to content

Commit

Permalink
[oneD] Implement DomainFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
ischoegl authored and speth committed Mar 18, 2023
1 parent 0c5fc1d commit a5172b1
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
74 changes: 74 additions & 0 deletions include/cantera/oneD/DomainFactory.h
@@ -0,0 +1,74 @@
//! @file DomainFactory.h

// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#ifndef DOMAIN_FACTORY_H
#define DOMAIN_FACTORY_H

#include "cantera/oneD/Domain1D.h"
#include "cantera/base/FactoryBase.h"

namespace Cantera
{

//! Factory class to create domain objects
//!
//! This class is mainly used via the newDomain() function, for example:
//!
//! ```cpp
//! shared_ptr<Domain1D> d1 = newDomain("Inlet", sol, "reactants");
//! ```
//!
//! @ingroup onedim
class DomainFactory : public Factory<Domain1D, shared_ptr<Solution>, const string&>
{
public:
/**
* Return a pointer to the factory. On the first call, a new instance is
* created. Since there is no need to instantiate more than one factory,
* on all subsequent calls, a pointer to the existing factory is returned.
*/
static DomainFactory* factory();

virtual void deleteFactory();

private:
//! Pointer to the single instance of the factory
static DomainFactory* s_factory;

//! default constructor, which is defined as private
DomainFactory();

//! Mutex for use when calling the factory
static std::mutex domain_mutex;
};

//! Create a Domain object of the specified type. An optional template argument will
//! dynamically cast Domain1D to the desired specialization.
//! @param domainType string identifying domain type.
//! @param solution Solution holding ThermoPhase, Kinetics and Transport objects.
//! @param id string identifier describing domain. If omitted, id defaults to the
//! domain type identifier.
//! @ingroup onedim
template <class T=Domain1D>
shared_ptr<T> newDomain(
const string& domainType, shared_ptr<Solution> solution, const string& id="")
{
string id_ = id;
if (id_ == "") {
id_ = domainType;
}
auto ret = std::dynamic_pointer_cast<T>(
shared_ptr<Domain1D>(
DomainFactory::factory()->create(domainType, solution, id_)));
if (!ret) {
throw CanteraError("newDomain",
"Invalid cast: unable to access 'Domain1D' as '{}'.", demangle(typeid(T)));
}
return ret;
}

}

#endif
74 changes: 74 additions & 0 deletions src/oneD/DomainFactory.cpp
@@ -0,0 +1,74 @@
//! @file DomainFactory.cpp

// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#include "cantera/oneD/DomainFactory.h"
#include "cantera/oneD/Boundary1D.h"
#include "cantera/oneD/StFlow.h"
#include "cantera/oneD/IonFlow.h"

namespace Cantera
{

DomainFactory* DomainFactory::s_factory = 0;
std::mutex DomainFactory::domain_mutex;

DomainFactory::DomainFactory()
{
reg("inlet", [](shared_ptr<Solution> solution, const string& id) {
return new Inlet1D(solution, id);
});
reg("empty", [](shared_ptr<Solution> solution, const string& id) {
return new Empty1D(solution, id);
});
reg("symmetry-plane", [](shared_ptr<Solution> solution, const string& id) {
return new Symm1D(solution, id);
});
reg("outlet", [](shared_ptr<Solution> solution, const string& id) {
return new Outlet1D(solution, id);
});
reg("outlet-reservoir", [](shared_ptr<Solution> solution, const string& id) {
return new OutletRes1D(solution, id);
});
reg("surface", [](shared_ptr<Solution> solution, const string& id) {
return new Surf1D(solution, id);
});
reg("reacting-surface", [](shared_ptr<Solution> solution, const string& id) {
return new ReactingSurf1D(solution, id);
});
reg("gas-flow", [](shared_ptr<Solution> solution, const string& id) {
return new StFlow(solution, id);
});
reg("ion-flow", [](shared_ptr<Solution> solution, const string& id) {
return new IonFlow(solution, id);
});
reg("free-flow", [](shared_ptr<Solution> solution, const string& id) {
StFlow* ret = new StFlow(solution, id);
ret->setFreeFlow();
return ret;
});
reg("axisymmetric-flow", [](shared_ptr<Solution> solution, const string& id) {
StFlow* ret = new StFlow(solution, id);
ret->setAxisymmetricFlow();
return ret;
});
}

DomainFactory* DomainFactory::factory()
{
std::unique_lock<std::mutex> lock(domain_mutex);
if (!s_factory) {
s_factory = new DomainFactory;
}
return s_factory;
}

void DomainFactory::deleteFactory()
{
std::unique_lock<std::mutex> lock(domain_mutex);
delete s_factory;
s_factory = 0;
}

}

0 comments on commit a5172b1

Please sign in to comment.