Hi Stefano,
The Solution class only works with bulk phases. For surface phases, you need to construct separate thermo and kinetics objects. The easiest way to do this is probably with the newPhase and newKinetics functions, using the versions that take an input file as one of the arguments. For example,
std::shared_ptr<Cantera::ThermoPhase> surface_(newPhase(filename, "surfPhaseName"));
std::vector<Cantera::ThermoPhase*> phases { surface_.get(), thermo_.get() };
std::shared_ptr<Cantera::Kinetics> surface_kinetic_(newKinetics(phases, filename, "surfPhaseName"));
Regards,
Ray
Hi Stefano,
The underlying objects will be of the SurfPhase
and InterfaceKinetics
types, because that is what is specified in the input file. However, the newPhase
and newKinetics
functions have to return pointers which only specify the base class, because the underlying type of the returned object could be any kind of ThermoPhase
or Kinetics
object. If you only need to access the functions that are available from the base class (which is hopefully the case), then you can just use the base class pointer. However, if you need access to the few functions that are only defined on these specific derived classes, e.g. SurfPhase::setSiteDensity
, then you will need to cast the pointer to the derived type, e.g.
std::shared_ptr<Cantera::SurfPhase> surf2 = std::dynamic_pointer_cast<Cantera::SurfPhase>(surface_);
Hope this helps.
Regards,
Ray
Hi Stefano,
I don’t see a declaration or initialization for surface_ptr
in your example. Is there something missing? If it’s not being initialized anywhere, then surface
is going to be a null pointer and generate the behavior that you’re observing.
Regards,
Ray
Hi Stefano,
I tried making minimal additions to your code to get a complete example, and wasn’t able to replicate the problem you described. The following code works just fine for me:
#include "cantera/thermo.h"
#include "cantera/transport.h"
#include "cantera/kinetics.h"
#include "cantera/thermo/SurfPhase.h"
#include "cantera/kinetics/InterfaceKinetics.h"
int main(int argc, char** argv) {
std::string filepath = "H2-O2-Rh.xml";
std::string gasPhase = "gas";
std::string surfPhase = "Rh_surface";
// Create gas phase as ThermoPhase
Cantera::ThermoPhase *thermo;
thermo = Cantera::newPhase(filepath, gasPhase);
// Create gas Transport from thermo
Cantera::Transport *transport;
{
transport = Cantera::newDefaultTransportMgr(thermo);
}
// Create gas kinetic reactions as Kinetics from thermo
Cantera::Kinetics *kinetic;
{
std::vector<Cantera::ThermoPhase *> gas_phases{thermo};
kinetic = Cantera::newKineticsMgr(thermo->xml(), gas_phases);
}
// Create surface phase as SurfPhase and surface kinetic as InterfaceKinetics
Cantera::SurfPhase *surface;
Cantera::InterfaceKinetics *surface_kinetic;
if (surfPhase != "none")
{
std::shared_ptr<Cantera::ThermoPhase> surface_as_thermo(Cantera::newPhase(filepath, surfPhase));
std::vector<Cantera::ThermoPhase *> gas_and_surface_phases{thermo, surface_as_thermo.get()};
std::shared_ptr<Cantera::Kinetics> surface_as_kinetic(Cantera::newKinetics(gas_and_surface_phases, filepath, surfPhase));
std::shared_ptr<Cantera::SurfPhase> surface_ptr = std::dynamic_pointer_cast<Cantera::SurfPhase>(surface_as_thermo);
std::shared_ptr
<Cantera::InterfaceKinetics> surface_kinetic_ptr = std::dynamic_pointer_cast<Cantera::InterfaceKinetics>(surface_as_kinetic);
surface = surface_ptr.get();
surface_kinetic = surface_kinetic_ptr.get();
for (auto& name : surface->speciesNames()) {
Cantera::writelog("{}\n", name);
}
}
return 0;
}
Regards,
Ray